private void BeginStatePartitionLoad( ProjectionMessage.Projections.CommittedEventReceived @event, Action loadCompleted) { string statePartition = _checkpointStrategy.StatePartitionSelector.GetStatePartition(@event); if (statePartition == "") // root is always cached { loadCompleted(); return; } string state = _partitionStateCache.TryGetAndLockPartitionState( statePartition, _checkpointStrategy.PositionTagger.MakeCheckpointTag(@event)); if (state != null) { loadCompleted(); } else { string partitionStateStreamName = MakePartitionStateStreamName(statePartition); _readDispatcher.Publish( new ClientMessage.ReadEventsBackwards( Guid.NewGuid(), new SendToThisEnvelope(this), partitionStateStreamName, -1, 1, resolveLinks: false), m => OnLoadStatePartitionCompleted(statePartition, @event, m, loadCompleted)); } }
private void FinilizeCommittedEventProcessing(ProjectionMessage.Projections.CommittedEventReceived message) { if (message.Data == null) { throw new NotSupportedException(); } if (_state == State.Faulted || _state == State.FaultedStopping) { return; } EnsureState(State.Running); //TODO: move to separate projection method and cache result in work item bool passedFilter = EventPassesFilter(message); if (passedFilter) { _lastProcessedEventPosition.Update(message); _eventsProcessedAfterRestart++; } else { if (EventPassesSourceFilter(message)) { _lastProcessedEventPosition.Update(message); } else { _lastProcessedEventPosition.UpdatePosition(message.Position); } } }
public void Handle(ProjectionMessage.Projections.CommittedEventReceived message) { Guid projectionId; if (_stopped) { return; } if (_headingEventDistributionPoint.Handle(message)) { return; } if (!_distributionPointSubscriptions.TryGetValue(message.CorrelationId, out projectionId)) { return; // unsubscribed } if (TrySubscribeHeadingDistributionPoint(message, projectionId)) { return; } if (message.Data != null) // means notification about the end of the stream/source { _projections[projectionId].Handle(message); } }
internal void BeginStatePartitionLoad( ProjectionMessage.Projections.CommittedEventReceived @event, Action loadCompleted) { string statePartition = _checkpointStrategy.StatePartitionSelector.GetStatePartition(@event); if (statePartition == "") // root is always cached { loadCompleted(); return; } string state = _partitionStateCache.TryGetAndLockPartitionState(statePartition, @event.CheckpointTag); if (state != null) { loadCompleted(); } else { string partitionStateStreamName = MakePartitionStateStreamName(statePartition); _readRequestsInProgress++; _readDispatcher.Publish( new ClientMessage.ReadStreamEventsBackward( Guid.NewGuid(), _readDispatcher.Envelope, partitionStateStreamName, -1, 1, resolveLinks: false), m => OnLoadStatePartitionCompleted(statePartition, @event, m, loadCompleted)); } }
private void DistributeMessage(ProjectionMessage.Projections.CommittedEventReceived message) { foreach (var subscriber in _headSubscribers.Values) { subscriber.Handle(message); } }
public CommittedEventWorkItem( CoreProjection projection, ProjectionMessage.Projections.CommittedEventReceived message, string partition) : base(projection, message.EventStreamId) { _message = message; _partition = partition; }
public void Update(ProjectionMessage.Projections.CommittedEventReceived comittedEvent) { var newTag = _positionTagger.MakeCheckpointTag(comittedEvent); UpdateByCheckpointTagForward(newTag); UpdatePosition(comittedEvent.Position); }
public override CheckpointTag MakeCheckpointTag(ProjectionMessage.Projections.CommittedEventReceived comittedEvent) { if (comittedEvent.PositionStreamId != _stream) { throw new InvalidOperationException(string.Format("Invalid stream '{0}'. Expected stream is '{1}'", comittedEvent.EventStreamId, _stream)); } return(CheckpointTag.FromStreamPosition(comittedEvent.PositionStreamId, comittedEvent.PositionSequenceNumber, comittedEvent.Position.PreparePosition)); }
public CommittedEventWorkItem( CoreProjection projection, ProjectionMessage.Projections.CommittedEventReceived message, string partition, CheckpointTag tag) : base(message.EventStreamId) { _projection = projection; _message = message; _partition = partition; _tag = tag; }
private bool ProcessEventByHandler( string partition, ProjectionMessage.Projections.CommittedEventReceived message, out string newState, out EmittedEvent[] emittedEvents) { SetHandlerState(partition); return(_projectionStateHandler.ProcessEvent( message.Position, message.EventStreamId, message.Data.EventType, _eventFilter.GetCategory(message.PositionStreamId), message.Data.EventId, message.EventSequenceNumber, Encoding.UTF8.GetString(message.Data.Metadata), Encoding.UTF8.GetString(message.Data.Data), out newState, out emittedEvents)); }
private void CacheRecentMessage(ProjectionMessage.Projections.CommittedEventReceived message) { _lastMessages.Enqueue(message); if (_lastMessages.Count > _eventCacheSize) { _lastMessages.Dequeue(); } var lastAvailableCommittedevent = _lastMessages.Peek(); _subscribeFromPosition = lastAvailableCommittedevent.Position; }
private void ProcessCommittedEvent( CommittedEventWorkItem committedEventWorkItem, ProjectionMessage.Projections.CommittedEventReceived message, string partition) { if (message.Data == null) { throw new NotSupportedException(); } EnsureState(State.Running); InternalProcessCommittedEvent(committedEventWorkItem, partition, message); }
private void ProcessEventFaulted(ProjectionMessage.Projections.CommittedEventReceived message, Exception ex) { _faultedReason = string.Format( "The {0} projection failed to process an event.\r\nHandler: {1}\r\nEvent Position: {2}\r\n\r\nMessage:\r\n\r\n{3}", _name, GetHandlerTypeName(), message.Position, ex.Message); if (_logger != null) { _logger.ErrorException(ex, _faultedReason); } GoToState(State.FaultedStopping); }
internal void FinalizeEventProcessing( List <EmittedEvent[]> scheduledWrites, ProjectionMessage.Projections.CommittedEventReceived committedEventReceived) { if (committedEventReceived.Data == null) { throw new NotSupportedException(); } if (_state != State.Faulted && _state != State.FaultedStopping) { EnsureState(State.Running); //TODO: move to separate projection method and cache result in work item var checkpointTag = committedEventReceived.CheckpointTag; _checkpointManager.EventProcessed(GetProjectionState(), scheduledWrites, checkpointTag); } }
private void InternalProcessCommittedEvent( CommittedEventWorkItem committedEventWorkItem, string partition, ProjectionMessage.Projections.CommittedEventReceived message) { string newState = null; EmittedEvent[] emittedEvents = null; //TODO: not emitting (optimized) projection handlers can skip serializing state on each processed event bool hasBeenProcessed; try { hasBeenProcessed = ProcessEventByHandler(partition, message, out newState, out emittedEvents); } catch (Exception ex) { ProcessEventFaulted( string.Format( "The {0} projection failed to process an event.\r\nHandler: {1}\r\nEvent Position: {2}\r\n\r\nMessage:\r\n\r\n{3}", _name, GetHandlerTypeName(), message.Position, ex.Message), ex); newState = null; emittedEvents = null; hasBeenProcessed = false; } newState = newState ?? ""; if (hasBeenProcessed) { if (!ProcessEmittedEvents(committedEventWorkItem, emittedEvents)) { return; } if (_partitionStateCache.GetLockedPartitionState(partition) != newState) // ensure state actually changed { var lockPartitionStateAt = partition != "" ? message.CheckpointTag : null; _partitionStateCache.CacheAndLockPartitionState(partition, newState, lockPartitionStateAt); if (_projectionConfig.PublishStateUpdates) { EmitStateUpdated(committedEventWorkItem, partition, newState); } } } }
private void InternalProcessCommittedEvent( CommittedEventWorkItem committedEventWorkItem, string partition, ProjectionMessage.Projections.CommittedEventReceived message) { string newState = null; EmittedEvent[] emittedEvents = null; //TODO: not emitting (optimized) projection handlers can skip serializing state on each processed event bool hasBeenProcessed; try { bool passedFilter = EventPassesFilter(message); hasBeenProcessed = passedFilter && ProcessEventByHandler(partition, message, out newState, out emittedEvents); } catch (Exception ex) { ProcessEventFaulted(message, ex); newState = null; emittedEvents = null; hasBeenProcessed = false; } newState = newState ?? ""; if (hasBeenProcessed) { if (_projectionConfig.EmitEventEnabled) { EmitEmittedEvents(committedEventWorkItem, emittedEvents); } if (_partitionStateCache.GetLockedPartitionState(partition) != newState) // ensure state actually changed { var lockPartitionStateAt = partition != "" ? _checkpointStrategy.PositionTagger.MakeCheckpointTag(message) : null; _partitionStateCache.CacheAndLockPartitionState(partition, newState, lockPartitionStateAt); if (_projectionConfig.PublishStateUpdates) { EmitStateUpdated(committedEventWorkItem, partition, newState); } } } }
public bool Handle(ProjectionMessage.Projections.CommittedEventReceived message) { if (message.CorrelationId != _distributionPointId) { return(false); } if (message.Data == null) { return(true); } CacheRecentMessage(message); DistributeMessage(message); if (_headSubscribers.Count == 0 && !_headDistributionPointPaused) { _headDistributionPoint.Pause(); _headDistributionPointPaused = true; } return(true); }
private void OnLoadStatePartitionCompleted( string partition, ProjectionMessage.Projections.CommittedEventReceived committedEventReceived, ClientMessage.ReadStreamEventsBackwardCompleted message, Action loadCompleted) { _readRequestsInProgress--; var positionTag = committedEventReceived.CheckpointTag; if (message.Events.Length == 1) { EventRecord @event = message.Events[0].Event; if (@event.EventType == "StateUpdated") { var checkpointTag = @event.Metadata.ParseJson <CheckpointTag>(); // always recovery mode? skip until state before current event //TODO: skip event processing in case we know i has been already processed CheckpointTag eventPositionTag = positionTag; if (checkpointTag < eventPositionTag) { _partitionStateCache.CacheAndLockPartitionState( partition, Encoding.UTF8.GetString(@event.Data), eventPositionTag); loadCompleted(); EnsureTickPending(); return; } } } if (message.NextEventNumber == -1) { _partitionStateCache.CacheAndLockPartitionState(partition, "", positionTag); loadCompleted(); EnsureTickPending(); return; } string partitionStateStreamName = MakePartitionStateStreamName(partition); _readRequestsInProgress++; _readDispatcher.Publish( new ClientMessage.ReadStreamEventsBackward( Guid.NewGuid(), _readDispatcher.Envelope, partitionStateStreamName, message.NextEventNumber, 1, resolveLinks: false), m => OnLoadStatePartitionCompleted(partition, committedEventReceived, m, loadCompleted)); }
public void Handle(ProjectionMessage.Projections.CommittedEventReceived message) { EnsureState( State.Running | State.Paused | State.Stopping | State.Stopped | State.FaultedStopping | State.Faulted); try { if (_state == State.Running || _state == State.Paused) { CheckpointTag eventTag = message.CheckpointTag; string partition = _checkpointStrategy.StatePartitionSelector.GetStatePartition(message); var committedEventWorkItem = new CommittedEventWorkItem(this, message, partition); _processingQueue.EnqueueTask(committedEventWorkItem, eventTag); } _processingQueue.ProcessEvent(); } catch (Exception ex) { SetFaulted(ex); } }
private bool TrySubscribeHeadingDistributionPoint(ProjectionMessage.Projections.CommittedEventReceived message, Guid projectionId) { if (_pausedProjections.Contains(projectionId)) { return(false); } var projectionSubscription = _projections[projectionId]; if (!_headingEventDistributionPoint.TrySubscribe( projectionId, projectionSubscription, projectionSubscription.MakeCheckpointTag(message))) { return(false); } Guid distributionPointId = message.CorrelationId; _distributionPoints[distributionPointId].Dispose(); _distributionPoints.Remove(distributionPointId); _distributionPointSubscriptions.Remove(distributionPointId); _projectionDistributionPoints[projectionId] = Guid.Empty; return(true); }
public void Handle(ProjectionMessage.Projections.CommittedEventReceived message) { EnsureState( State.Running | State.Paused | State.Stopping | State.Stopped | State.FaultedStopping | State.Faulted); if (_state == State.Stopping || _state == State.Stopped || _state == State.FaultedStopping || _state == State.Faulted) { return; // ignore remaining events } CheckpointTag eventTag = _checkpointStrategy.PositionTagger.MakeCheckpointTag(message); ValidateQueueingOrder(eventTag); string partition = _checkpointStrategy.StatePartitionSelector.GetStatePartition(message); #if PROJECTIONS_ASSERTS if (!string.IsNullOrEmpty(partition)) { int lastSequenceInParittion; if (_lastSequencesByPartition.TryGetValue(partition, out lastSequenceInParittion)) { if (message.EventSequenceNumber != lastSequenceInParittion + 1) { throw new Exception( string.Format( "Invalid event number sequence detected in parittion '{0}' Expected: {1} Received: {2}", message.EventStreamId, lastSequenceInParittion + 1, message.EventSequenceNumber)); } } _lastSequencesByPartition[partition] = message.EventSequenceNumber; } #endif _pendingEvents.Enqueue(new CommittedEventWorkItem(this, message, partition, eventTag)); if (_state == State.Running) { ProcessOneEvent(); } }
public void Handle(ProjectionMessage.Projections.CommittedEventReceived message) { HandledMessages.Add(message); }
public override string GetStatePartition(ProjectionMessage.Projections.CommittedEventReceived @event) { return(""); }
public abstract string GetStatePartition(ProjectionMessage.Projections.CommittedEventReceived @event);
private bool EventPassesSourceFilter(ProjectionMessage.Projections.CommittedEventReceived message) { //TODO: support category return(_eventFilter.PassesSource(message.ResolvedLinkTo, message.PositionStreamId)); }
public virtual CheckpointTag MakeCheckpointTag(ProjectionMessage.Projections.CommittedEventReceived comittedEvent) { return(new CheckpointTag(comittedEvent.Position)); }