示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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();
            }
        }
示例#4
0
        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();
            }
        }
示例#5
0
 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);
        }
示例#7
0
        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));
        }
示例#8
0
        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);
        }
示例#9
0
 private void Start(Action onStarted)
 {
     if (!Enabled)
     {
         throw new InvalidOperationException("Projection is disabled");
     }
     _onStarted = onStarted;
     _state     = ManagedProjectionState.Starting;
     _coreQueue.Publish(new CoreProjectionManagementMessage.Start(_id));
 }
示例#10
0
 public void Handle(CoreProjectionManagementMessage.Started message)
 {
     _state = ManagedProjectionState.Running;
     if (_onStarted != null)
     {
         var action = _onStarted;
         _onStarted = null;
         action();
     }
 }
示例#11
0
        public void Handle(ProjectionMessage.Projections.StatusReport.Stopped message)
        {
            _state = ManagedProjectionState.Stopped;
            DisposeCoreProjection();
            var stopCompleted = _stopCompleted;

            _stopCompleted = null;
            if (stopCompleted != null)
            {
                stopCompleted();
            }
        }
示例#12
0
 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");
     }
 }
示例#13
0
 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;
 }
示例#14
0
        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();
        }
示例#15
0
        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));
        }
示例#16
0
 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));
 }
示例#17
0
        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);
        }
示例#18
0
 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");
     }
 }
示例#19
0
        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));
        }
示例#20
0
 public void Handle(CoreProjectionManagementMessage.Stopped message)
 {
     _state = message.Completed ? ManagedProjectionState.Completed : ManagedProjectionState.Stopped;
     OnStoppedOrFaulted();
 }
示例#21
0
 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;
 }
示例#22
0
 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();
     }
 }
示例#23
0
 public void Handle(CoreProjectionManagementMessage.Prepared message)
 {
     _state = ManagedProjectionState.Prepared;
     _persistedState.SourceDefintion = message.SourceDefintion;
     OnPrepared();
 }
示例#24
0
        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);
        }
示例#25
0
        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);
        }
示例#26
0
 public void Handle(CoreProjectionManagementMessage.Started message)
 {
     _state = ManagedProjectionState.Running;
     if (_onStarted != null)
     {
         var action = _onStarted;
         _onStarted = null;
         action();
     }
 }
        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();
            }
        }
示例#28
0
 private void LoadStopped(Action onLoaded)
 {
     _onStopped = onLoaded;
     _state     = ManagedProjectionState.LoadingState;
     _coreQueue.Publish(new CoreProjectionManagementMessage.LoadStopped(Id));
 }
示例#29
0
 private void StartNew(Action completed)
 {
     _state = ManagedProjectionState.Stopped;
     StartIfEnabled();
     if (completed != null) completed();
 }
示例#30
0
        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();
        }
示例#31
0
        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));
        }
示例#32
0
 public void InitializeExisting(string name)
 {
     _state = ManagedProjectionState.Loading;
     BeginLoad(name);
 }
示例#33
0
 public void Handle(CoreProjectionManagementMessage.Prepared message)
 {
     _state = ManagedProjectionState.Prepared;
     _persistedState.SourceDefinition = message.SourceDefinition;
     OnPrepared();
 }
示例#34
0
 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));
 }
示例#35
0
        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);
        }
示例#36
0
 private void LoadStopped(Action onLoaded)
 {
     _onStopped = onLoaded;
     _state = ManagedProjectionState.LoadingState;
     _coreQueue.Publish(new CoreProjectionManagementMessage.LoadStopped(Id));
 }
示例#37
0
        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();
            }
        }
示例#38
0
        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);
        }
示例#39
0
 public void Handle(CoreProjectionManagementMessage.Stopped message)
 {
     _state = message.Completed ? ManagedProjectionState.Completed : ManagedProjectionState.Stopped;
     OnStoppedOrFaulted();
 }
示例#40
0
 public void Handle(CoreProjectionManagementMessage.Stopped message)
 {
     _state = ManagedProjectionState.Stopped;
     DisposeCoreProjection();
     var stopCompleted = _stopCompleted;
     _stopCompleted = null;
     if (stopCompleted != null) stopCompleted();
 }
示例#41
0
 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");
     }
 }
示例#42
0
 public void InitializeExisting(string name)
 {
     _state = ManagedProjectionState.Loading;
     BeginLoad(name);
 }
示例#43
0
        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);
        }
示例#44
0
        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);
        }
示例#45
0
 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));
 }
示例#46
0
 private void Start(Action onStarted)
 {
     if (!Enabled)
         throw new InvalidOperationException("Projection is disabled");
     _onStarted = onStarted;
     _state = ManagedProjectionState.Starting;
     _coreQueue.Publish(new CoreProjectionManagementMessage.Start(_id));
 }
示例#47
0
 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();
 }
示例#49
0
 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();
     }
 }