public void OnAfterPersisted(EventStream eventStream) { var evnt = eventStream.FindEvent<UserRegistered>(); var collection = GetMongoCollection(); var document = collection.FindOneById(new BsonString(evnt.UserId.ToString())); document["Status"] = 2; collection.Save(document); }
public void OnBeforePersisting(EventStream eventStream) { var evnt = eventStream.FindEvent<UserRegistered>(); GetMongoCollection().Insert(new BsonDocument { { "_id", evnt.UserId.ToString() }, { "UserName", evnt.UserName }, { "Status", 1 } }); }
public void Append(EventStream stream) { if (stream != null) { if (!_eventDict.TryAdd(new EventKey(stream.AggregateRootId, stream.Version), stream)) { throw new ConcurrentException(""); } } }
public void Send(EventStream eventStream) { var eventQueue = _eventQueueRouter.Route(eventStream); if (eventQueue == null) { throw new Exception("Could not route event stream to an appropriate uncommitted event queue."); } eventQueue.Enqueue(eventStream); }
public void Publish(EventStream stream) { var eventQueue = _eventQueueRouter.Route(stream); if (eventQueue == null) { throw new Exception("Could not route event stream to an appropriate event queue."); } eventQueue.Enqueue(stream); }
public string GetTopic(EventStream eventStream) { if (Interlocked.Increment(ref _index) % 2 == 0) { return "NoteEventTopic2"; } else { return "NoteEventTopic1"; } }
public void PublishEvent(IDictionary<string, string> contextItems, EventStream eventStream) { var eventMessage = ConvertToData(contextItems, eventStream); var topic = _eventTopicProvider.GetTopic(eventStream); var data = _binarySerializer.Serialize(eventMessage); var message = new Message(topic, data); var result = _producer.Send(message, eventStream.AggregateRootId); if (result.SendStatus != SendStatus.Success) { throw new ENodeException("Publish event failed, eventStream:[{0}]", eventStream); } }
/// <summary>Append the event stream to the event store. /// </summary> public void Append(EventStream stream) { if (stream == null) { return; } var count = _redisClient.HSetNX(stream.AggregateRootId.Replace("-", string.Empty), Encoding.UTF8.GetBytes(stream.Version.ToString()), _binarySerializer.Serialize(stream)); if (count == 0) { throw new ConcurrentException(); } }
public ICommittedEventQueue Route(EventStream stream) { if (_eventQueues == null) { _eventQueues = Configuration.Instance.GetCommitedEventQueues().ToArray(); } if (_eventQueues.Length > 0) { return _eventQueues[(Interlocked.Increment(ref _index) - 1) % _eventQueues.Length]; } return null; }
public MessageExecuteResult Execute(EventStream stream) { //If it is the first event stream of the aggregate, then do the event dispatching logic directly. if (stream.Version == 1) { var result = DoDispatchingLogic(stream); if (result == DispatchResult.None || result == DispatchResult.Success || result == DispatchResult.RePublished) { return MessageExecuteResult.Executed; } else if (result == DispatchResult.Failed) { return MessageExecuteResult.Failed; } } var lastEventPublishedVersion = _eventPublishInfoStore.GetEventPublishedVersion(stream.AggregateRootId); //If the last published event stream version + 1 is smaller than the current event stream version. //That means there must be some event streams which before the current event stream have not been published yet. //So in this case, we should retry to publish the event stream. if (lastEventPublishedVersion + 1 < stream.Version) { RePublishEventStream(stream); return MessageExecuteResult.Executed; } //If the current event stream is exactly the next event stream version, then do the event dispatching logic. else if (lastEventPublishedVersion + 1 == stream.Version) { var result = DoDispatchingLogic(stream); if (result == DispatchResult.None || result == DispatchResult.Success || result == DispatchResult.RePublished) { return MessageExecuteResult.Executed; } else if (result == DispatchResult.Failed) { return MessageExecuteResult.Failed; } } return MessageExecuteResult.Executed; }
/// <summary>Retry the given command. /// </summary> /// <param name="commandInfo"></param> /// <param name="eventStream"></param> /// <param name="errorInfo"></param> /// <param name="retrySuccessCallbackAction"></param> public void RetryCommand(CommandInfo commandInfo, EventStream eventStream, ErrorInfo errorInfo, Action retrySuccessCallbackAction) { if (_retryCommandQueue == null) { _retryCommandQueue = Configuration.Instance.GetRetryCommandQueue(); } var command = commandInfo.Command; if (commandInfo.RetriedCount < command.RetryCount) { _retryService.TryAction("TryEnqueueCommand", () => TryEnqueueCommand(commandInfo), 3, retrySuccessCallbackAction); } else { _commandAsyncResultManager.TryComplete(command.Id, eventStream.AggregateRootId, errorInfo); _logger.InfoFormat("{0} retried count reached to its max retry count {1}.", command.GetType().Name, command.RetryCount); if (retrySuccessCallbackAction != null) { retrySuccessCallbackAction(); } } }
/// <summary>Append the event stream to the event store. /// </summary> /// <param name="stream"></param> public void Append(EventStream stream) { if (stream == null) { return; } try { var aggregateRootType = _aggregateRootTypeProvider.GetAggregateRootType(stream.AggregateRootName); var collectionName = _eventCollectionNameProvider.GetCollectionName(stream.AggregateRootId, aggregateRootType); var collection = GetMongoCollection(collectionName); collection.Insert(ToMongoEventStream(stream)); } catch (Exception ex) { if (ex.Message.Contains("duplicate key error index")) { throw new ConcurrentException(); } throw; } }
public void Refresh(EventStream stream) { var aggregateRootType = _aggregateRootTypeProvider.GetAggregateRootType(stream.AggregateRootName); if (aggregateRootType == null) { throw new Exception(string.Format("Could not find aggregate root type by aggregate root name {0}", stream.AggregateRootName)); } if (stream.Version == 1) { var aggregateRoot = _aggregateRootFactory.CreateAggregateRoot(aggregateRootType); aggregateRoot.ReplayEvent(stream); _memoryCache.Set(aggregateRoot); } else if (stream.Version > 1) { var aggregateRoot = _memoryCache.Get(stream.AggregateRootId); if (aggregateRoot == null) { aggregateRoot = _repository.Get(aggregateRootType, stream.AggregateRootId); _memoryCache.Set(aggregateRoot); } else if (aggregateRoot.Version + 1 == stream.Version) { aggregateRoot.ReplayEvent(stream); _memoryCache.Set(aggregateRoot); } else if (aggregateRoot.Version + 1 < stream.Version) { aggregateRoot = _repository.Get(aggregateRootType, stream.AggregateRootId); _memoryCache.Set(aggregateRoot); } } }
private BsonDocument ToMongoEventStream(EventStream stream) { var events = stream.Events.Select(x => _binarySerializer.Serialize(x)); var document = new BsonDocument { { "_id", new BsonDocument { { "AggregateRootId", stream.AggregateRootId }, { "Version", stream.Version } } }, { "Id", stream.Id.ToString() }, { "AggregateRootName", stream.AggregateRootName }, { "AggregateRootId", stream.AggregateRootId }, { "Version", stream.Version }, { "CommandId", stream.CommandId.ToString() }, { "Timestamp", stream.Timestamp }, { "Events", new BsonArray(events) } }; return document; }
public bool IsSynchronizeTo(EventStream eventStream) { return eventStream.HasEvent<UserRegistered>(); }
public EventProcessingContext(IAggregateRoot aggregateRoot, EventStream eventStream, ProcessingCommand processingCommand) { AggregateRoot = aggregateRoot; EventStream = eventStream; ProcessingCommand = processingCommand; }
private void DispatchEventStreamToEventHandlers(EventStream stream) { foreach (var evnt in stream.Events) { foreach (var eventHandler in _eventHandlerProvider.GetEventHandlers(evnt.GetType())) { DispatchEventToEventHandler(eventHandler, evnt, 0, 3); } } }
private void UpdatePublishedEventStreamVersion(EventStream stream) { if (stream.Version == 1) { _eventPublishInfoStore.InsertFirstPublishedVersion(stream.AggregateRootId); } else { _eventPublishInfoStore.UpdatePublishedVersion(stream.AggregateRootId, stream.Version); } }
private EventStreamPersistResult PersistEventStream(EventStream stream) { try { _eventStore.Append(stream); return EventStreamPersistResult.Success; } catch (Exception ex) { return ProcessException(ex, stream); } }
public string GetTopic(EventStream eventStream) { return "BankTransferEventTopic"; }
private DispatchResult DoDispatchingLogic(EventStream eventStream) { var isDispatched = false; try { DispatchEventStreamToEventHandlers(eventStream); isDispatched = true; UpdatePublishedEventStreamVersion(eventStream); return DispatchResult.Success; } catch (Exception ex) { _logger.Error(string.Format("Exception raised when dispatching event stream:{0}", eventStream.GetStreamInformation()), ex); if (!isDispatched) { RePublishEventStream(eventStream); return DispatchResult.RePublished; } else { return DispatchResult.Failed; } } }
private EventStreamPersistResult ProcessException(Exception exception, EventStream stream) { if (exception is ConcurrentException) { if (IsEventStreamCommitted(stream)) { return EventStreamPersistResult.Success; } var commandInfo = _processingCommandCache.Get(stream.CommandId); _logger.Error(string.Format( "Concurrent exception raised when persisting event stream, command:{0}, event stream info:{1}", commandInfo.Command.GetType().Name, stream.GetStreamInformation()), exception); //Enforce to refresh memory cache before retring the command //to enusre that when we retring the command, the memeory cache is at the latest status. _memoryCacheRefreshService.Refresh(_aggregateRootTypeProvider.GetAggregateRootType(stream.AggregateRootName), stream.AggregateRootId); _retryCommandService.RetryCommand(commandInfo, exception); return EventStreamPersistResult.Retried; } else { var commandInfo = _processingCommandCache.Get(stream.CommandId); _logger.Error(string.Format( "Unknown exception raised when persisting event stream, command:{0}, event stream info:{1}", commandInfo.Command.GetType().Name, stream.GetStreamInformation()), exception); return EventStreamPersistResult.UnknownException; } }
private EventMessage ConvertToData(IDictionary<string, string> contextItems, EventStream eventStream) { var data = new EventMessage(); data.CommitId = eventStream.CommitId; data.AggregateRootId = eventStream.AggregateRootId; data.AggregateRootTypeCode = eventStream.AggregateRootTypeCode; data.Timestamp = eventStream.Timestamp; data.Version = eventStream.Version; data.ContextItems = contextItems; foreach (var evnt in eventStream.Events) { var typeCode = _eventTypeCodeProvider.GetTypeCode(evnt.GetType()); var eventData = _binarySerializer.Serialize(evnt); data.Events.Add(new EventEntry(typeCode, eventData)); } return data; }
private bool CommitEventStream(EventStream stream) { bool executed = false; //Persist event stream. var result = PersistEventStream(stream); if (result == EventStreamPersistResult.Success) { //Refresh memory cache. try { _memoryCacheRefreshService.Refresh(stream); } catch (Exception ex) { _logger.Error(string.Format("Unknown exception raised when refreshing memory cache for event stream:{0}", stream.GetStreamInformation()), ex); } //Publish event stream. try { _eventPublisher.Publish(stream); executed = true; } catch (Exception ex) { _logger.Error(string.Format("Unknown exception raised when publishing event stream:{0}", stream.GetStreamInformation()), ex); } //Complete command async result if exist. _commandAsyncResultManager.TryComplete(stream.CommandId, null); } else if (result == EventStreamPersistResult.Retried) { executed = true; } return executed; }
public void OnEventProcessed(EventStream eventStream) { EventProcessedAction(eventStream, this); }
private void EventHandledCallback(EventStream eventStream, EventProcessContext eventProcessContext) { IMessageContext messageContext; if (_messageContextDict.TryRemove(eventStream.CommitId, out messageContext)) { messageContext.OnMessageHandled(eventProcessContext.QueueMessage); } if (eventProcessContext.EventMessage.ContextItems != null && eventProcessContext.EventMessage.ContextItems.ContainsKey("DomainEventHandledMessageTopic")) { var domainEventHandledMessageTopic = eventProcessContext.EventMessage.ContextItems["DomainEventHandledMessageTopic"] as string; var processCompletedEvent = eventStream.Events.FirstOrDefault(x => x is IProcessCompletedEvent) as IProcessCompletedEvent; var processId = default(string); var isProcessCompletedEvent = false; if (processCompletedEvent != null) { isProcessCompletedEvent = true; processId = processCompletedEvent.ProcessId; } _domainEventHandledMessageSender.Send(new DomainEventHandledMessage { CommandId = eventStream.CommitId, AggregateRootId = eventStream.AggregateRootId, IsProcessCompletedEvent = isProcessCompletedEvent, ProcessId = processId }, domainEventHandledMessageTopic); } }
public string GetTopic(EventStream eventStream) { return "NoteEventTopic"; }
private DispatchEventStreamResult DoDispatchingLogic(EventStream stream) { var isDispatched = false; try { DispatchEventStreamToEventHandlers(stream); isDispatched = true; UpdatePublishedEventStreamVersion(stream); return DispatchEventStreamResult.Success; } catch (Exception ex) { _logger.Error(ex); if (!isDispatched) { RePublishEventStream(stream); return DispatchEventStreamResult.RePublished; } else { return DispatchEventStreamResult.Failed; } } }
private void RePublishEventStream(EventStream stream) { _eventPublisher.Publish(stream); }
private bool IsEventStreamCommitted(EventStream stream) { return _eventStore.IsEventStreamExist(stream.AggregateRootId, _aggregateRootTypeProvider.GetAggregateRootType(stream.AggregateRootName), stream.Id); }