private void LoadCompleted(ClientMessage.ReadStreamEventsBackwardCompleted completed) { if (completed.Result == ReadStreamResult.Success && completed.Events.Length == 1) { byte[] state = completed.Events[0].Event.Data; var persistedState = state.ParseJson <PersistedState>(); _lastWrittenVersion = completed.Events[0].Event.EventNumber; FixUpOldFormat(completed, persistedState); FixupOldProjectionModes(persistedState); FixUpOldProjectionRunAs(persistedState); LoadPersistedState(persistedState); //TODO: encapsulate this into managed projection _state = ManagedProjectionState.Loaded; if (Enabled && _enabledToRun) { if (Mode >= ProjectionMode.Continuous) { Prepare(() => Start(() => { })); } } else { CreatePrepared(() => LoadStopped(() => { })); } return; } _state = ManagedProjectionState.Creating; _logger.Trace( "Projection manager did not find any projection configuration records in the {0} stream. Projection stays in CREATING state", completed.EventStreamId); }
private void BeginCreatePrepared(ProjectionConfig config, Action onPrepared) { _onPrepared = onPrepared; if (config == null) { throw new ArgumentNullException("config"); } //TODO: which states are allowed here? if (_state >= ManagedProjectionState.Preparing) { DisposeCoreProjection(); _state = ManagedProjectionState.Loaded; } //TODO: load configuration from the definition if (_persistedState.SourceDefinition == null) { throw new Exception( "The projection cannot be loaded as stopped as it was stored in the old format. Update the projection query text to force prepare"); } var createProjectionMessage = new CoreProjectionManagementMessage.CreatePrepared( new PublishEnvelope(_inputQueue), Id, _name, new ProjectionVersion(_projectionId, _persistedState.Epoch ?? 0, _persistedState.Version ?? 1), config, _persistedState.SourceDefinition, HandlerType, Query); //note: set running before start as coreProjection.start() can respond with faulted _state = ManagedProjectionState.Preparing; _coreQueue.Publish(createProjectionMessage); }
private void Stop(Action completed) { switch (_state) { case ManagedProjectionState.Stopped: case ManagedProjectionState.Faulted: if (completed != null) { completed(); } return; case ManagedProjectionState.Loading: case ManagedProjectionState.Creating: throw new InvalidOperationException( string.Format( "Cannot stop a projection in the '{0}' state", Enum.GetName(typeof(ManagedProjectionState), _state))); case ManagedProjectionState.Stopping: _stopCompleted += completed; return; case ManagedProjectionState.Running: _state = ManagedProjectionState.Stopping; _stopCompleted = completed; _coreQueue.Publish(new ProjectionMessage.Projections.Management.Stop(_id)); break; default: throw new NotSupportedException(); } }
internal void SetState(ManagedProjectionState value) { // _logger.Trace("MP: {0} {1} => {2}", _name, _state, value); _state = value; switch (value) { case ManagedProjectionState.Aborted: _stateHandler = new AbortedState(this); break; case ManagedProjectionState.Aborting: _stateHandler = new AbortingState(this); break; case ManagedProjectionState.Completed: _stateHandler = new CompletedState(this); break; case ManagedProjectionState.Creating: case ManagedProjectionState.Loading: case ManagedProjectionState.Loaded: _stateHandler = new CreatingLoadingLoadedState(this); break; case ManagedProjectionState.Faulted: _stateHandler = new FaultedState(this); break; case ManagedProjectionState.LoadingStopped: _stateHandler = new LoadingStateState(this); break; case ManagedProjectionState.Prepared: _stateHandler = new PreparedState(this); break; case ManagedProjectionState.Preparing: _stateHandler = new PreparingState(this); break; case ManagedProjectionState.Running: _stateHandler = new RunningState(this); break; case ManagedProjectionState.Starting: _stateHandler = new StartingState(this); break; case ManagedProjectionState.Stopped: _stateHandler = new StoppedState(this); break; case ManagedProjectionState.Stopping: _stateHandler = new StoppingState(this); break; default: throw new Exception(); } }
private void StartNew(Action completed) { _state = ManagedProjectionState.Stopped; StartIfEnabled(); if (completed != null) { completed(); } }
protected override IEnumerable<WhenStep> When() { _projectionId = Guid.NewGuid(); _bufferedEvents = 100; _checkpointStatus = "checkpoint-status"; _coreProcessingTime = 10; _resultStreamName = "result-stream"; _effectiveName = "effective-name"; _enabled = true; _epoch = 10; _eventsProcessedAfterRestart = 12345; _lastCheckpoint = "last-chgeckpoint"; _masterStatus = ManagedProjectionState.Completed; _mode = ProjectionMode.OneTime; _partitionsCached = 123; _name = "name"; _position = CheckpointTag.FromPosition(0, 1000, 900).ToString(); _progress = 100; _projectionIdNum = 1234; _readsInProgress = 2; _stateReason = "reason"; _status = "status"; _version = 1; _writePendingEventsAfterCheckpoint = 3; _writePendingEventsBeforeCheckpoint = 4; _writesInProgress = 5; yield return CreateWriteEvent("$projections-$master", "$statistics-report", @"{ ""id"":""" + _projectionId.ToString("N") + @""", ""statistics"":{ ""bufferedEvents"":""" + _bufferedEvents + @""", ""checkpointStatus"":""" + _checkpointStatus + @""", ""coreProcessingTime"":""" + _coreProcessingTime + @""", ""resultStreamName"":""" + _resultStreamName + @""", ""effectiveName"":""" + _effectiveName + @""", ""enabled"":""" + _enabled + @""", ""epoch"":""" + _epoch + @""", ""eventsProcessedAfterRestart"":""" + _eventsProcessedAfterRestart + @""", ""lastCheckpoint"":""" + _lastCheckpoint + @""", ""masterStatus"":""" + _masterStatus + @""", ""mode"":""" + _mode + @""", ""partitionsCached"":""" + _partitionsCached + @""", ""name"":""" + _name + @""", ""position"":""" + _position + @""", ""progress"":""" + _progress + @""", ""projectionId"":""" + _projectionIdNum + @""", ""readsInProgress"":""" + _readsInProgress + @""", ""stateReason"":""" + _stateReason + @""", ""status"":""" + _status + @""", ""version"":""" + _version + @""", ""writePendingEventsAfterCheckpoint"":""" + _writePendingEventsAfterCheckpoint + @""", ""writePendingEventsBeforeCheckpoint"":""" + _writePendingEventsBeforeCheckpoint + @""", ""writesInProgress"":""" + _writesInProgress + @""", } }", null, true); }
protected override IEnumerable <WhenStep> When() { _projectionId = Guid.NewGuid(); _bufferedEvents = 100; _checkpointStatus = "checkpoint-status"; _coreProcessingTime = 10; _resultStreamName = "result-stream"; _effectiveName = "effective-name"; _enabled = true; _epoch = 10; _eventsProcessedAfterRestart = 12345; _lastCheckpoint = "last-chgeckpoint"; _masterStatus = ManagedProjectionState.Completed; _mode = ProjectionMode.OneTime; _partitionsCached = 123; _name = "name"; _position = CheckpointTag.FromPosition(0, 1000, 900).ToString(); _progress = 100; _projectionIdNum = 1234; _readsInProgress = 2; _stateReason = "reason"; _status = "status"; _version = 1; _writePendingEventsAfterCheckpoint = 3; _writePendingEventsBeforeCheckpoint = 4; _writesInProgress = 5; yield return(CreateWriteEvent("$projections-$master", "$statistics-report", @"{ ""id"":""" + _projectionId.ToString("N") + @""", ""statistics"":{ ""bufferedEvents"":""" + _bufferedEvents + @""", ""checkpointStatus"":""" + _checkpointStatus + @""", ""coreProcessingTime"":""" + _coreProcessingTime + @""", ""resultStreamName"":""" + _resultStreamName + @""", ""effectiveName"":""" + _effectiveName + @""", ""enabled"":""" + _enabled + @""", ""epoch"":""" + _epoch + @""", ""eventsProcessedAfterRestart"":""" + _eventsProcessedAfterRestart + @""", ""lastCheckpoint"":""" + _lastCheckpoint + @""", ""masterStatus"":""" + _masterStatus + @""", ""mode"":""" + _mode + @""", ""partitionsCached"":""" + _partitionsCached + @""", ""name"":""" + _name + @""", ""position"":""" + _position + @""", ""progress"":""" + _progress + @""", ""projectionId"":""" + _projectionIdNum + @""", ""readsInProgress"":""" + _readsInProgress + @""", ""stateReason"":""" + _stateReason + @""", ""status"":""" + _status + @""", ""version"":""" + _version + @""", ""writePendingEventsAfterCheckpoint"":""" + _writePendingEventsAfterCheckpoint + @""", ""writePendingEventsBeforeCheckpoint"":""" + _writePendingEventsBeforeCheckpoint + @""", ""writesInProgress"":""" + _writesInProgress + @""", } }", null, true)); }
private void BeginCreateAndPrepare( ProjectionStateHandlerFactory handlerFactory, ProjectionConfig config, Action onPrepared) { _onPrepared = onPrepared; if (handlerFactory == null) { throw new ArgumentNullException("handlerFactory"); } if (config == null) { throw new ArgumentNullException("config"); } //TODO: which states are allowed here? if (_state >= ManagedProjectionState.Preparing) { throw new InvalidOperationException("Already preparing or has been prepared"); } //TODO: load configuration from the definition var createProjectionMessage = new CoreProjectionManagementMessage.CreateAndPrepare( new PublishEnvelope(_inputQueue), _id, _name, config, delegate { // this delegate runs in the context of a projection core thread // TODO: move this code to the projection core service as we may be in different processes in the future IProjectionStateHandler stateHandler = null; try { stateHandler = handlerFactory.Create(HandlerType, Query, Console.WriteLine); var checkpointStrategyBuilder = new CheckpointStrategy.Builder(); stateHandler.ConfigureSourceProcessingStrategy(checkpointStrategyBuilder); checkpointStrategyBuilder.Validate(Mode); // avoid future exceptions in coreprojection return(stateHandler); } catch (Exception ex) { SetFaulted( string.Format( "Cannot create a projection state handler.\r\n\r\nHandler type: {0}\r\nQuery:\r\n\r\n{1}\r\n\r\nMessage:\r\n\r\n{2}", HandlerType, Query, ex.Message), ex); if (stateHandler != null) { stateHandler.Dispose(); } throw; } }); //note: set runnign before start as coreProjection.start() can respond with faulted _state = ManagedProjectionState.Preparing; _coreQueue.Publish(createProjectionMessage); }
private void Start(Action onStarted) { if (!Enabled) { throw new InvalidOperationException("Projection is disabled"); } _onStarted = onStarted; _state = ManagedProjectionState.Starting; _coreQueue.Publish(new CoreProjectionManagementMessage.Start(_id)); }
public void Handle(CoreProjectionManagementMessage.Started message) { _state = ManagedProjectionState.Running; if (_onStarted != null) { var action = _onStarted; _onStarted = null; action(); } }
public void Handle(ProjectionMessage.Projections.StatusReport.Stopped message) { _state = ManagedProjectionState.Stopped; DisposeCoreProjection(); var stopCompleted = _stopCompleted; _stopCompleted = null; if (stopCompleted != null) { stopCompleted(); } }
public void Handle(CoreProjectionManagementMessage.Prepared message) { _persistedState.SourceDefinition = message.SourceDefinition; if (_state == ManagedProjectionState.Preparing) { _state = ManagedProjectionState.Prepared; OnPrepared(); } else { _logger.Trace("Received prepared without being prepared"); } }
private void SetFaulted(string reason, Exception ex = null) { if (ex != null) { _logger.ErrorException(ex, "The '{0}' projection faulted due to '{1}'", _name, reason); } else { _logger.Error("The '{0}' projection faulted due to '{1}'", _name, reason); } _state = ManagedProjectionState.Faulted; _faultedReason = reason; }
private void Start(IPublisher coreOutput, ProjectionStateHandlerFactory handlerFactory, ProjectionConfig config) { if (coreOutput == null) { throw new ArgumentNullException("coreOutput"); } if (handlerFactory == null) { throw new ArgumentNullException("handlerFactory"); } if (config == null) { throw new ArgumentNullException("config"); } if (_coreProjection != null) { throw new InvalidOperationException("CoreProjection has been already created"); } IProjectionStateHandler stateHandler = null; try { stateHandler = handlerFactory.Create(HandlerType, Query, Console.WriteLine); var checkpointStrategyBuilder = new CheckpointStrategy.Builder(); stateHandler.ConfigureSourceProcessingStrategy(checkpointStrategyBuilder); checkpointStrategyBuilder.Validate(this.Mode); // avoid future exceptions in coreprojection // constructor can fail if wrong source defintion //TODO: revise it _coreProjection = new CoreProjection(_name, _id, coreOutput, stateHandler, config, _logger); } catch (Exception ex) { SetFaulted( String.Format( "Cannot create a projection state handler.\r\n\r\nHandler type: {0}\r\nQuery:\r\n\r\n{1}\r\n\r\nMessage:\r\n\r\n{2}", HandlerType, Query, ex.Message), ex); if (stateHandler != null) { stateHandler.Dispose(); } return; } //TODO: load configuration from the definition _state = ManagedProjectionState.Running; //note: set runnign before start as coreProjection.start() can respond with faulted _coreProjection.Start(); }
private void Start(ProjectionStateHandlerFactory handlerFactory, ProjectionConfig config) { if (handlerFactory == null) { throw new ArgumentNullException("handlerFactory"); } if (config == null) { throw new ArgumentNullException("config"); } if (_state == ManagedProjectionState.Running) { throw new InvalidOperationException("Already started"); } //TODO: load configuration from the definition var createProjectionMessage = new ProjectionMessage.CoreService.Management.Create(new PublishEnvelope(_inputQueue), _id, _name, config, delegate { IProjectionStateHandler stateHandler = null; try { stateHandler = handlerFactory.Create(this.HandlerType, this.Query, Console.WriteLine); var checkpointStrategyBuilder = new CheckpointStrategy.Builder(); stateHandler.ConfigureSourceProcessingStrategy(checkpointStrategyBuilder); checkpointStrategyBuilder.Validate(Mode); // avoid future exceptions in coreprojection return(stateHandler); } catch (Exception ex) { SetFaulted(String.Format("Cannot create a projection state handler.\r\n\r\nHandler type: {0}\r\nQuery:\r\n\r\n{1}\r\n\r\nMessage:\r\n\r\n{2}", HandlerType, Query, ex.Message), ex); if (stateHandler != null) { stateHandler.Dispose(); } throw; } }); //note: set runnign before start as coreProjection.start() can respond with faulted _state = ManagedProjectionState.Running; _coreQueue.Publish(createProjectionMessage); _coreQueue.Publish(new ProjectionMessage.Projections.Management.Start(_id)); }
private void Start(Action completed) { if (!Enabled) { throw new InvalidOperationException("Projection is disabled"); } _onStopped = _onStarted = () => { _onStopped = null; _onStarted = null; if (completed != null) { completed(); } }; _state = ManagedProjectionState.Starting; _coreQueue.Publish(new CoreProjectionManagementMessage.Start(Id)); }
private void LoadCompleted(ClientMessage.ReadStreamEventsBackwardCompleted completed) { if (completed.Result == RangeReadResult.Success && completed.Events.Length == 1) { byte[] state = completed.Events[0].Event.Data; LoadPersistedState(state.ParseJson <PersistedState>()); //TODO: encapsulate this into managed projection _state = ManagedProjectionState.Stopped; StartIfEnabled(); return; } _state = ManagedProjectionState.Creating; _logger.Trace( "Projection manager did not find any projection configuration records in the {0} stream. Projection stays in CREATING state", completed.EventStreamId); }
private void WriteCompleted( ClientMessage.WriteEventsCompleted message, ManagedProjectionState completedState, Action completed, string eventStreamId) { if (_state != ManagedProjectionState.Writing) { _logger.Error("Projection definition write completed in non writing state. ({0})", _name); } if (message.Result == OperationResult.Success) { _logger.Info("'{0}' projection source has been written", _name); var writtenEventNumber = message.FirstEventNumber; if (writtenEventNumber != (_persistedState.Version ?? writtenEventNumber)) { throw new Exception("Projection version and event number mismatch"); } _lastWrittenVersion = (_persistedState.Version ?? writtenEventNumber); _state = completedState; if (completed != null) { completed(); } return; } _logger.Info( "Projection '{0}' source has not been written to {1}. Error: {2}", _name, eventStreamId, Enum.GetName(typeof(OperationResult), message.Result)); if (message.Result == OperationResult.CommitTimeout || message.Result == OperationResult.ForwardTimeout || message.Result == OperationResult.PrepareTimeout || message.Result == OperationResult.WrongExpectedVersion) { _logger.Info("Retrying write projection source for {0}", _name); BeginWrite(completed); } else { throw new NotSupportedException("Unsupported error code received"); } }
private void BeginWrite(Action completed) { if (Mode == ProjectionMode.Transient) { //TODO: move to common completion procedure _lastWrittenVersion = _persistedState.Version ?? -1; completed(); return; } var oldState = _state; _state = ManagedProjectionState.Writing; var managedProjectionSerializedState = _persistedState.ToJsonBytes(); var eventStreamId = "$projections-" + _name; var corrId = Guid.NewGuid(); _writeDispatcher.Publish( new ClientMessage.WriteEvents( corrId, corrId, _writeDispatcher.Envelope, true, eventStreamId, ExpectedVersion.Any, new Event(Guid.NewGuid(), "$ProjectionUpdated", true, managedProjectionSerializedState, Empty.ByteArray), SystemAccount.Principal), m => WriteCompleted(m, oldState, completed, eventStreamId)); }
public void Handle(CoreProjectionManagementMessage.Stopped message) { _state = message.Completed ? ManagedProjectionState.Completed : ManagedProjectionState.Stopped; OnStoppedOrFaulted(); }
private void SetFaulted(string reason, Exception ex = null) { if (ex != null) _logger.ErrorException(ex, "The '{0}' projection faulted due to '{1}'", _name, reason); else _logger.Error("The '{0}' projection faulted due to '{1}'", _name, reason); _state = ManagedProjectionState.Faulted; _faultedReason = reason; }
private void Stop(Action completed) { switch (_state) { case ManagedProjectionState.Stopped: case ManagedProjectionState.Faulted: if (completed != null) completed(); return; case ManagedProjectionState.Loading: case ManagedProjectionState.Creating: throw new InvalidOperationException( string.Format( "Cannot stop a projection in the '{0}' state", Enum.GetName(typeof (ManagedProjectionState), _state))); case ManagedProjectionState.Stopping: _stopCompleted += completed; return; case ManagedProjectionState.Running: case ManagedProjectionState.Starting: _state = ManagedProjectionState.Stopping; _stopCompleted = completed; _coreQueue.Publish(new CoreProjectionManagementMessage.Stop(_id)); break; default: throw new NotSupportedException(); } }
public void Handle(CoreProjectionManagementMessage.Prepared message) { _state = ManagedProjectionState.Prepared; _persistedState.SourceDefintion = message.SourceDefintion; OnPrepared(); }
private void BeginCreateAndPrepare( ProjectionStateHandlerFactory handlerFactory, ProjectionConfig config, Action onPrepared) { _onPrepared = onPrepared; if (handlerFactory == null) throw new ArgumentNullException("handlerFactory"); if (config == null) throw new ArgumentNullException("config"); //TODO: which states are allowed here? if (_state >= ManagedProjectionState.Preparing) throw new InvalidOperationException("Already preparing or has been prepared"); //TODO: load configuration from the definition var createProjectionMessage = new CoreProjectionManagementMessage.CreateAndPrepare( new PublishEnvelope(_inputQueue), _id, _name, config, delegate { // this delegate runs in the context of a projection core thread // TODO: move this code to the projection core service as we may be in different processes in the future IProjectionStateHandler stateHandler = null; try { stateHandler = handlerFactory.Create(HandlerType, Query, Console.WriteLine); var checkpointStrategyBuilder = new CheckpointStrategy.Builder(); stateHandler.ConfigureSourceProcessingStrategy(checkpointStrategyBuilder); checkpointStrategyBuilder.Validate(Mode); // avoid future exceptions in coreprojection return stateHandler; } catch (Exception ex) { SetFaulted( string.Format( "Cannot create a projection state handler.\r\n\r\nHandler type: {0}\r\nQuery:\r\n\r\n{1}\r\n\r\nMessage:\r\n\r\n{2}", HandlerType, Query, ex.Message), ex); if (stateHandler != null) stateHandler.Dispose(); throw; } }); //note: set runnign before start as coreProjection.start() can respond with faulted _state = ManagedProjectionState.Preparing; _coreQueue.Publish(createProjectionMessage); }
private void BeginCreateAndPrepare( ProjectionStateHandlerFactory handlerFactory, ProjectionConfig config, Action onPrepared) { _onPrepared = _onStopped = () => { _onStopped = null; _onPrepared = null; if (onPrepared != null) onPrepared(); }; if (handlerFactory == null) throw new ArgumentNullException("handlerFactory"); if (config == null) throw new ArgumentNullException("config"); //TODO: which states are allowed here? if (_state >= ManagedProjectionState.Preparing) { DisposeCoreProjection(); _state = ManagedProjectionState.Loaded; } //TODO: load configuration from the definition Func<IProjectionStateHandler> stateHandlerFactory = delegate { // this delegate runs in the context of a projection core thread // TODO: move this code to the projection core service as we may be in different processes in the future IProjectionStateHandler stateHandler = null; try { stateHandler = handlerFactory.Create( HandlerType, Query, logger: s => _logger.Trace(s), cancelCallbackFactory: _timeoutScheduler == null ? (Action<int, Action>) null : _timeoutScheduler.Schedule); return stateHandler; } catch (Exception ex) { SetFaulted( string.Format( "Cannot create a projection state handler.\r\n\r\nHandler type: {0}\r\nQuery:\r\n\r\n{1}\r\n\r\nMessage:\r\n\r\n{2}", HandlerType, Query, ex.Message), ex); if (stateHandler != null) stateHandler.Dispose(); throw; } }; var createProjectionMessage = _isSlave ? (Message) new CoreProjectionManagementMessage.CreateAndPrepareSlave( new PublishEnvelope(_inputQueue), Id, _name, new ProjectionVersion(_projectionId, _persistedState.Epoch ?? 0, _persistedState.Version ?? 0), config, _slaveResultsPublisher, _slaveMasterCorrelationId, stateHandlerFactory) : new CoreProjectionManagementMessage.CreateAndPrepare( new PublishEnvelope(_inputQueue), Id, _name, new ProjectionVersion(_projectionId, _persistedState.Epoch ?? 0, _persistedState.Version ?? 0), config, HandlerType, Query, stateHandlerFactory); //note: set runnign before start as coreProjection.start() can respond with faulted _state = ManagedProjectionState.Preparing; _coreQueue.Publish(createProjectionMessage); }
internal void SetState(ManagedProjectionState value) { _state = value; switch (value) { case ManagedProjectionState.Aborted: _stateHandler = new AbortedState(this); break; case ManagedProjectionState.Aborting: _stateHandler = new AbortingState(this); break; case ManagedProjectionState.Completed: _stateHandler = new CompletedState(this); break; case ManagedProjectionState.Creating: case ManagedProjectionState.Loading: case ManagedProjectionState.Loaded: _stateHandler = new CreatingLoadingLoadedState(this); break; case ManagedProjectionState.Faulted: _stateHandler = new FaultedState(this); break; case ManagedProjectionState.LoadingStopped: _stateHandler = new LoadingStateState(this); break; case ManagedProjectionState.Prepared: _stateHandler = new PreparedState(this); break; case ManagedProjectionState.Preparing: _stateHandler = new PreparingState(this); break; case ManagedProjectionState.Running: _stateHandler = new RunningState(this); break; case ManagedProjectionState.Starting: _stateHandler = new StartingState(this); break; case ManagedProjectionState.Stopped: _stateHandler = new StoppedState(this); break; case ManagedProjectionState.Stopping: _stateHandler = new StoppingState(this); break; case ManagedProjectionState.Deleting: _stateHandler = new DeletingState(this); break; default: throw new Exception(); } }
private void LoadStopped(Action onLoaded) { _onStopped = onLoaded; _state = ManagedProjectionState.LoadingState; _coreQueue.Publish(new CoreProjectionManagementMessage.LoadStopped(Id)); }
private void StartNew(Action completed) { _state = ManagedProjectionState.Stopped; StartIfEnabled(); if (completed != null) completed(); }
private void Start(IPublisher coreOutput, ProjectionStateHandlerFactory handlerFactory, ProjectionConfig config) { if (coreOutput == null) throw new ArgumentNullException("coreOutput"); if (handlerFactory == null) throw new ArgumentNullException("handlerFactory"); if (config == null) throw new ArgumentNullException("config"); if (_coreProjection != null) throw new InvalidOperationException("CoreProjection has been already created"); IProjectionStateHandler stateHandler = null; try { stateHandler = handlerFactory.Create(HandlerType, Query, Console.WriteLine); var checkpointStrategyBuilder = new CheckpointStrategy.Builder(); stateHandler.ConfigureSourceProcessingStrategy(checkpointStrategyBuilder); checkpointStrategyBuilder.Validate(this.Mode); // avoid future exceptions in coreprojection // constructor can fail if wrong source defintion //TODO: revise it _coreProjection = new CoreProjection(_name, _id, coreOutput, stateHandler, config, _logger); } catch (Exception ex) { SetFaulted( String.Format( "Cannot create a projection state handler.\r\n\r\nHandler type: {0}\r\nQuery:\r\n\r\n{1}\r\n\r\nMessage:\r\n\r\n{2}", HandlerType, Query, ex.Message), ex); if (stateHandler != null) stateHandler.Dispose(); return; } //TODO: load configuration from the definition _state = ManagedProjectionState.Running; //note: set runnign before start as coreProjection.start() can respond with faulted _coreProjection.Start(); }
private void Start(ProjectionStateHandlerFactory handlerFactory, ProjectionConfig config) { if (handlerFactory == null) throw new ArgumentNullException("handlerFactory"); if (config == null) throw new ArgumentNullException("config"); if (_state == ManagedProjectionState.Running) throw new InvalidOperationException("Already started"); //TODO: load configuration from the definition var createProjectionMessage = new ProjectionMessage.CoreService.Management.Create(new PublishEnvelope(_inputQueue), _id, _name, config, delegate { IProjectionStateHandler stateHandler = null; try { stateHandler = handlerFactory.Create(this.HandlerType, this.Query, Console.WriteLine); var checkpointStrategyBuilder = new CheckpointStrategy.Builder(); stateHandler.ConfigureSourceProcessingStrategy(checkpointStrategyBuilder); checkpointStrategyBuilder.Validate(Mode); // avoid future exceptions in coreprojection return stateHandler; } catch (Exception ex) { SetFaulted(String.Format("Cannot create a projection state handler.\r\n\r\nHandler type: {0}\r\nQuery:\r\n\r\n{1}\r\n\r\nMessage:\r\n\r\n{2}", HandlerType, Query, ex.Message), ex); if (stateHandler != null) stateHandler.Dispose(); throw; } }); //note: set runnign before start as coreProjection.start() can respond with faulted _state = ManagedProjectionState.Running; _coreQueue.Publish(createProjectionMessage); _coreQueue.Publish(new ProjectionMessage.Projections.Management.Start(_id)); }
public void InitializeExisting(string name) { _state = ManagedProjectionState.Loading; BeginLoad(name); }
public void Handle(CoreProjectionManagementMessage.Prepared message) { _state = ManagedProjectionState.Prepared; _persistedState.SourceDefinition = message.SourceDefinition; OnPrepared(); }
private void Start(Action completed) { if (!Enabled) throw new InvalidOperationException("Projection is disabled"); _onStopped = _onStarted = () => { _onStopped = null; _onStarted = null; if (completed != null) completed(); }; _state = ManagedProjectionState.Starting; _coreQueue.Publish(new CoreProjectionManagementMessage.Start(Id)); }
private void BeginCreateAndPrepare( ProjectionStateHandlerFactory handlerFactory, ProjectionConfig config, Action onPrepared) { _onPrepared = _onStopped = () => { _onStopped = null; _onPrepared = null; if (onPrepared != null) { onPrepared(); } }; if (handlerFactory == null) { throw new ArgumentNullException("handlerFactory"); } if (config == null) { throw new ArgumentNullException("config"); } //TODO: which states are allowed here? if (_state >= ManagedProjectionState.Preparing) { DisposeCoreProjection(); _state = ManagedProjectionState.Loaded; } //TODO: load configuration from the definition Func <IProjectionStateHandler> stateHandlerFactory = delegate { // this delegate runs in the context of a projection core thread // TODO: move this code to the projection core service as we may be in different processes in the future IProjectionStateHandler stateHandler = null; try { stateHandler = handlerFactory.Create( HandlerType, Query, logger: s => _logger.Trace(s), cancelCallbackFactory: _timeoutScheduler == null ? (Action <int, Action>)null : _timeoutScheduler.Schedule); return(stateHandler); } catch (Exception ex) { SetFaulted( string.Format( "Cannot create a projection state handler.\r\n\r\nHandler type: {0}\r\nQuery:\r\n\r\n{1}\r\n\r\nMessage:\r\n\r\n{2}", HandlerType, Query, ex.Message), ex); if (stateHandler != null) { stateHandler.Dispose(); } throw; } }; var createProjectionMessage = _isSlave ? (Message) new CoreProjectionManagementMessage.CreateAndPrepareSlave( new PublishEnvelope(_inputQueue), Id, _name, new ProjectionVersion(_projectionId, _persistedState.Epoch ?? 0, _persistedState.Version ?? 0), config, _slaveResultsPublisher, _slaveMasterCorrelationId, stateHandlerFactory) : new CoreProjectionManagementMessage.CreateAndPrepare( new PublishEnvelope(_inputQueue), Id, _name, new ProjectionVersion(_projectionId, _persistedState.Epoch ?? 0, _persistedState.Version ?? 0), config, HandlerType, Query, stateHandlerFactory); //note: set runnign before start as coreProjection.start() can respond with faulted _state = ManagedProjectionState.Preparing; _coreQueue.Publish(createProjectionMessage); }
private void BeginCreatePrepared(ProjectionConfig config, Action onPrepared) { _onPrepared = onPrepared; if (config == null) throw new ArgumentNullException("config"); //TODO: which states are allowed here? if (_state >= ManagedProjectionState.Preparing) { DisposeCoreProjection(); _state = ManagedProjectionState.Loaded; } //TODO: load configuration from the definition if (_persistedState.SourceDefinition == null) throw new Exception( "The projection cannot be loaded as stopped as it was stored in the old format. Update the projection query text to force prepare"); var createProjectionMessage = new CoreProjectionManagementMessage.CreatePrepared( new PublishEnvelope(_inputQueue), Id, _name, new ProjectionVersion(_projectionId, _persistedState.Epoch ?? 0, _persistedState.Version ?? 1), config, _persistedState.SourceDefinition, HandlerType, Query); //note: set running before start as coreProjection.start() can respond with faulted _state = ManagedProjectionState.Preparing; _coreQueue.Publish(createProjectionMessage); }
public void Handle(CoreProjectionManagementMessage.Stopped message) { _state = ManagedProjectionState.Stopped; DisposeCoreProjection(); var stopCompleted = _stopCompleted; _stopCompleted = null; if (stopCompleted != null) stopCompleted(); }
private void LoadCompleted(ClientMessage.ReadStreamEventsBackwardCompleted completed) { if (completed.Result == ReadStreamResult.Success && completed.Events.Length == 1) { byte[] state = completed.Events[0].Event.Data; var persistedState = state.ParseJson<PersistedState>(); _lastWrittenVersion = completed.Events[0].Event.EventNumber; FixUpOldFormat(completed, persistedState); FixupOldProjectionModes(persistedState); FixUpOldProjectionRunAs(persistedState); LoadPersistedState(persistedState); //TODO: encapsulate this into managed projection _state = ManagedProjectionState.Loaded; if (Enabled && _enabledToRun) { if (Mode >= ProjectionMode.Continuous) Prepare(() => Start(() => { })); } else CreatePrepared(() => LoadStopped(() => { })); return; } _state = ManagedProjectionState.Creating; _logger.Trace( "Projection manager did not find any projection configuration records in the {0} stream. Projection stays in CREATING state", completed.EventStreamId); }
private void LoadCompleted(ClientMessage.ReadStreamEventsBackwardCompleted completed) { if (completed.Result == RangeReadResult.Success && completed.Events.Length == 1) { byte[] state = completed.Events[0].Event.Data; LoadPersistedState(state.ParseJson<PersistedState>()); //TODO: encapsulate this into managed projection _state = ManagedProjectionState.Stopped; if (Enabled) Prepare(() => Start(() => { })); return; } _state = ManagedProjectionState.Creating; _logger.Trace( "Projection manager did not find any projection configuration records in the {0} stream. Projection stays in CREATING state", completed.EventStreamId); }
private void Start(Action onStarted) { if (!Enabled) throw new InvalidOperationException("Projection is disabled"); _onStarted = onStarted; _state = ManagedProjectionState.Starting; _coreQueue.Publish(new CoreProjectionManagementMessage.Start(_id)); }
private void WriteCompleted( ClientMessage.WriteEventsCompleted message, ManagedProjectionState completedState, Action completed, string eventStreamId) { if (_state != ManagedProjectionState.Writing) { _logger.Error("Projection definition write completed in non writing state. ({0})", _name); } if (message.Result == OperationResult.Success) { _logger.Info("'{0}' projection source has been written", _name); var writtenEventNumber = message.FirstEventNumber; if (writtenEventNumber != (_persistedState.Version ?? writtenEventNumber)) throw new Exception("Projection version and event number mismatch"); _lastWrittenVersion = (_persistedState.Version ?? writtenEventNumber); _state = completedState; if (completed != null) completed(); return; } _logger.Info( "Projection '{0}' source has not been written to {1}. Error: {2}", _name, eventStreamId, Enum.GetName(typeof (OperationResult), message.Result)); if (message.Result == OperationResult.CommitTimeout || message.Result == OperationResult.ForwardTimeout || message.Result == OperationResult.PrepareTimeout || message.Result == OperationResult.WrongExpectedVersion) { _logger.Info("Retrying write projection source for {0}", _name); BeginWrite(completed); } else throw new NotSupportedException("Unsupported error code received"); }
public void Handle(CoreProjectionManagementMessage.Stopped message) { _state = ManagedProjectionState.Stopped; FireStoppedOrFaulted(); }