async Task TryGetAndPublishEventStreamAsync(ProcessingCommand processingCommand) { var command = processingCommand.Command; var commandId = command.Id; var aggregateRootId = command.AggregateRootId; var result = await Policy .Handle <Exception>() .OrResult <AsyncExecutedResult <EventStream> >(r => !r.Succeeded) .WaitAndRetryForeverAsync( retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (delegateResult, retryCount, retryAttempt) => logger.LogError(delegateResult.Exception ?? delegateResult.Result.Exception, $"获取已产生的事件失败,重试。 [CommandType = {command.GetType()}, CommandId = {commandId}, AggregateRootId = {aggregateRootId}, RetryCount = {retryCount}, RetryAttempt = {retryAttempt}]")) .ExecuteAsync(() => eventStore.GetByCommandIdAsync(aggregateRootId, commandId)); if (result.Succeeded) { var eventStream = result.Data; if (eventStream != null) { logger.LogDebug($"获取已产生的事件成功,发布事件。 [CommandType = {command.GetType()}, CommandId = {commandId}, AggregateRootId = {aggregateRootId}, EventStream = {eventStream}]"); await PublishEventStreamAsync(processingCommand, eventStream); } else { logger.LogWarning($"未获取到任何已产生的事件,命令未处理任何聚合根。 [CommandType = {command.GetType()}, CommandId = {commandId}, AggregateRootId = {aggregateRootId}]"); await processingCommand.OnQueueProcessedAsync(CommandExecutedStatus.NothingChanged, "未获取到任何已产生的事件,命令未处理任何聚合根。"); } } else { logger.LogError(result.Exception, $"获取已产生的事件失败。 [CommandType = {command.GetType()}, CommandId = {commandId}, AggregateRootId = {aggregateRootId}]"); } }
Task TryGetAndHandleCommandAsync(ProcessingCommand processingCommand) { var command = processingCommand.Command; var commandType = command.GetType(); using (var serviceScope = serviceProvider.CreateScope()) { var handlerType = typeof(ICommandHandler <>).GetTypeInfo().MakeGenericType(commandType); var handlers = serviceScope.ServiceProvider.GetServices(handlerType)?.Cast <ICommandHandler>(); if (handlers?.Count() == 1) { var handler = handlers.First(); handlerMapping[commandType] = handler; return(HandleCommandAsync(processingCommand, handler)); } if (handlers?.Count() > 1) { logger.LogError($"注册超过 1 个命令处理器。 [CommandType = {commandType}, CommandId = {command.Id}, CommandHandlerTypes = [{string.Join(" | ", handlers.Select(item => item.GetType()))}]]"); return(processingCommand.OnQueueProcessedAsync(CommandExecutedStatus.Failed, "注册超过 1 个命令处理器。")); } return(TryGetAndAsyncHandleCommandAsync(processingCommand)); } }
Task TryGetAndCommitEvent(ProcessingCommand processingCommand, IProcessingCommandHandlerContext context) { var command = processingCommand.Command; var commandType = command.GetType(); var commandId = command.Id; var aggregateRoots = context.GetAggregateRoots().Where(a => a.GetUncommittedEvents().Any()); if (aggregateRoots?.Count() == 1) { var aggregateRoot = aggregateRoots.First(); var aggregateRootType = aggregateRoot.GetType(); var aggregateRootId = aggregateRoot.Id; var eventStream = new EventStream( commandId, aggregateRootType.FullName, aggregateRootId, aggregateRoot.Version + 1, aggregateRoot.GetUncommittedEvents()); var committingEvent = new CommittingEvent(eventStream, processingCommand, aggregateRoot); logger.LogDebug($"获取命令产生的事件成功,提交并发布事件!"); return(eventCommitter.CommitAsync(committingEvent)); } if (aggregateRoots?.Count() > 1) { logger.LogError($"命令处理超过 1 个聚合根。 [CommandType = {commandType}, CommandId = {commandId}, AggregateRoots = [{string.Join(" | ", aggregateRoots.Select(a => $"Type = {a.GetType()}, Id = {a.Id}"))}]]"); return(processingCommand.OnQueueProcessedAsync(CommandExecutedStatus.Failed, "命令处理超过 1 个聚合根。")); } logger.LogWarning($"命令未处理任何聚合根,尝试获取是否已有事件产生并发布。 [CommandType = {commandType}, CommandId = {commandId}]"); return(TryGetAndPublishEventStreamAsync(processingCommand)); }
public async Task ProcessAsync(ProcessingCommand processingCommand, CommandExecutedResult executedResult) { using (await asyncLock.LockAsync()) { lastActiveOn = DateTime.UtcNow; try { if (processingCommand.QueueSequence == previousSequence + 1) { queue.TryRemove(processingCommand.QueueSequence); previousSequence = await ProcessWaitingAsync(processingCommand.QueueSequence); } else if (processingCommand.QueueSequence > previousSequence + 1) { waitingQueue[processingCommand.QueueSequence] = executedResult; } else { queue.TryRemove(processingCommand.QueueSequence); await executedResultProcessor.ProcessAsync(processingCommand, executedResult); waitingQueue.TryRemove(processingCommand.QueueSequence); } } catch (Exception ex) { logger.LogError(ex, $"队列处理失败。 [AggregateRootId = {aggregateRootId}, CommandType = {processingCommand.Command.GetType()}, CommandId = {processingCommand.Command.Id}]"); } } }
public void Enqueue(ProcessingCommand processingCommand) { lock (syncLock) { processingCommand.QueueSequence = nextSequence; processingCommand.Queue = this; if (queue.TryAdd(processingCommand.QueueSequence, processingCommand)) { nextSequence++; } } lastActiveOn = DateTime.UtcNow; TryStart(); }
public Task HandleAsync(ProcessingCommand processingCommand) { var command = processingCommand.Command; var commandType = command.GetType(); if (string.IsNullOrWhiteSpace(command.AggregateRootId)) { logger.LogError($"命令处理的聚合根 Id 不能为空。 [CommandType = {commandType}, CommandId = {command.Id}]"); return(processingCommand.OnQueueProcessedAsync(CommandExecutedStatus.Failed, "命令处理的聚合根 Id 不能为空。")); } if (handlerMapping.TryGetValue(commandType, out var handler)) { return(HandleCommandAsync(processingCommand, handler)); } return(TryGetAndHandleCommandAsync(processingCommand)); }
async Task HandleCommandAsync(ProcessingCommand processingCommand, ICommandHandler handler) { var command = processingCommand.Command; var commandType = command.GetType(); var handlerType = handler.GetType(); try { var context = contextFactory.Create(); var handlerMethod = handlerType.GetTypeInfo().GetMethod("HandleAsync", new[] { context.GetType(), commandType }); await(Task) handlerMethod.Invoke(handler, new object[] { context, command }); logger.LogDebug($"命令处理器执行成功,尝试获取已产生的事件并提交。 [CommandType = {commandType}, CommandId = {command.Id}, CommandHandlerType = {handlerType}]"); await TryGetAndCommitEvent(processingCommand, context); } catch (Exception ex) { logger.LogWarning(ex, $"命令处理器执行失败,尝试获取已存储的事件。 [CommandType = {commandType}, CommandId = {command.Id}, CommandHandlerType = {handlerType}]"); await TryGetAndPublishEventStreamAsync(processingCommand); } }
async Task PublishApplicationMessageAsync(ProcessingCommand processingCommand, IApplicationMessage applicationMessage) { var result = await Policy .Handle <Exception>() .OrResult <AsyncExecutedResult>(r => !r.Succeeded) .WaitAndRetryForeverAsync( retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (delegateResult, retryCount, retryAttempt) => logger.LogError(delegateResult.Exception ?? delegateResult.Result.Exception, $"命令产生的应用消息发布失败,重试。 [CommandType = {processingCommand.Command.GetType()}, CommandId = {processingCommand.Command.Id}, ApplicationMessageType = {applicationMessage.GetType()}, ApplicationMessageId = {applicationMessage.Id}, ApplicationMessageRoutingKey = {applicationMessage.GetRoutingKey()}, RetryCount = {retryCount}, RetryAttempt = {retryAttempt}]")) .ExecuteAsync(() => applicationMessagePublisher.PublishAsync(applicationMessage)); if (result.Succeeded) { logger.LogDebug($"命令产生的应用消息发布成功。 [CommandType = {processingCommand.Command.GetType()}, CommandId = {processingCommand.Command.Id}, ApplicationMessageType = {applicationMessage.GetType()}, ApplicationMessageId = {applicationMessage.Id}, ApplicationMessageRoutingKey = {applicationMessage.GetRoutingKey()}]"); await processingCommand.OnQueueProcessedAsync(CommandExecutedStatus.Succeeded, objectSerializer.Serialize(applicationMessage), applicationMessage.GetTag()); } else { logger.LogDebug(result.Exception, $"命令产生的应用消息发布失败。 [CommandType = {processingCommand.Command.GetType()}, CommandId = {processingCommand.Command.Id}, ApplicationMessageType = {applicationMessage.GetType()}, ApplicationMessageId = {applicationMessage.Id}, ApplicationMessageRoutingKey = {applicationMessage.GetRoutingKey()}]"); } }
async Task PublishEventStreamAsync(ProcessingCommand processingCommand, EventStream eventStream) { var command = processingCommand.Command; var result = await Policy .Handle <Exception>() .OrResult <AsyncExecutedResult>(r => !r.Succeeded) .WaitAndRetryForeverAsync( retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (delegateResult, retryCount, retryAttempt) => logger.LogError(delegateResult.Exception ?? delegateResult.Result.Exception, $"命令产生的事件发布失败,重试。 [CommandType = {command.GetType()}, CommandId = {command.Id}, EventStream = {eventStream}, RetryCount = {retryCount}, RetryAttempt = {retryAttempt}]")) .ExecuteAsync(() => eventPublisher.PublishStreamAsync(eventStream)); if (result.Succeeded) { logger.LogDebug($"命令产生的事件发布成功。 [CommandType = {command.GetType()}, CommandId = {command.Id}, EventStream = {eventStream}]"); await processingCommand.OnQueueProcessedAsync(CommandExecutedStatus.Succeeded); } else { logger.LogError(result.Exception, $"命令产生的事件发布失败。 [CommandType = {command.GetType()}, CommandId = {command.Id}, EventStream = {eventStream}]"); } }
async Task AsyncHandleCommandAsync(ProcessingCommand processingCommand, ICommandAsyncHandler asyncHandler) { var command = processingCommand.Command; var commandType = command.GetType(); var asyncHandlerType = asyncHandler.GetType(); try { var asyncHandlerMethod = asyncHandlerType.GetTypeInfo().GetMethod("HandleAsync", new[] { commandType }); var result = await(Task <AsyncExecutedResult <IApplicationMessage> >) asyncHandlerMethod.Invoke(asyncHandler, new [] { command }); if (result.Succeeded) { var applicationMessage = result.Data; if (applicationMessage != null) { logger.LogDebug($"异步命令处理器执行成功,发布产生的应用消息。 [CommandType = {commandType}, CommandId = {command.Id}, CommandAsyncHandlerType = {asyncHandlerType}, ApplicationMessageType = {applicationMessage.GetType()}, ApplicationMessageId = {applicationMessage.Id}, ApplicationMessageRoutingKey = {applicationMessage.GetRoutingKey()}]"); await PublishApplicationMessageAsync(processingCommand, applicationMessage); } else { logger.LogDebug($"异步命令处理器执行成功,未产生任何应用消息。 [CommandType = {commandType}, CommandId = {command.Id}, CommandAsyncHandlerType = {asyncHandlerType}]"); await processingCommand.OnQueueProcessedAsync(CommandExecutedStatus.Succeeded, "命令异步处理器执行成功,未产生任何应用消息。"); } } else { logger.LogError($"异步命令处理器执行失败。 [CommandType = {commandType}, CommandId = {command.Id}, CommandAsyncHandlerType = {asyncHandlerType}]"); await processingCommand.OnQueueProcessedAsync(CommandExecutedStatus.Failed, "异步命令处理器执行失败。"); } } catch (Exception ex) { logger.LogError(ex, $"异步命令处理器执行失败。 [CommandType = {commandType}, CommandId = {command.Id}, CommandAsyncHandlerType = {asyncHandlerType}]"); await processingCommand.OnQueueProcessedAsync(CommandExecutedStatus.Failed, "异步命令处理器执行失败。"); } }
public Task ProcessAsync(ProcessingCommand processingCommand, CommandExecutedResult result) => Task.CompletedTask;