//public static async Task<T> HandleAsync<T>(this IHandlerProvider handlerProvider, IResolverSession session,
        //    string scopeId, string actionId, object[] requests, CancellationToken cancellationToken)
        //{
        //    var actionBytes = new byte[4];
        //    actionBytes.AddBytes<int>(actionId, 4, 0);

        //    return await HandleAsync<T>(handlerProvider, session, scopeId, actionBytes, requests, cancellationToken);
        //}

        public static async Task <T> HandleAsync <T>(this IHandlerProvider handlerProvider, IResolverSession session,
                                                     string scopeId, string actionId, object[] requests, CancellationToken cancellationToken)
        {
            var parameterTypes = requests.Where(r => !(r is CancellationToken)).Select(r => r.GetType()).ToArray();
            var returnType     = typeof(T);
            var parameterHash  = TypeHasher.GetMethodBytes(parameterTypes, returnType, t => t.Name);

            //var scopeBytes = Encoding.UTF8.GetBytes(scopeId);
            var actionHash = TypeHasher.CreateMD5Hash(Encoding.UTF8.GetBytes($"scope-{scopeId}:action-{actionId}"), parameterHash);

            var handler = handlerProvider.GetHandler(actionHash.ToByteArray());

            return((T)await handler.HandleAsync(session, requests, cancellationToken));
        }
        void ConsumeMessage(BrokeredMessage brokeredMessage)
        {
            var          commandContext = new MessageContext(brokeredMessage);
            var          message        = commandContext.Message as ICommand;
            MessageReply messageReply   = null;

            if (message == null)
            {
                return;
            }
            var           needRetry         = message.NeedRetry;
            bool          commandHasHandled = false;
            IMessageStore messageStore      = null;

            try
            {
                PerMessageContextLifetimeManager.CurrentMessageContext = commandContext;
                messageStore      = IoCFactory.Resolve <IMessageStore>();
                commandHasHandled = messageStore.HasCommandHandled(commandContext.MessageID);
                if (!commandHasHandled)
                {
                    var messageHandler = _handlerProvider.GetHandler(message.GetType());
                    _logger.InfoFormat("Handle command, commandID:{0}", commandContext.MessageID);

                    if (messageHandler == null)
                    {
                        messageReply = new MessageReply(commandContext.MessageID, new NoHandlerExists());
                    }
                    else
                    {
                        //var unitOfWork = IoCFactory.Resolve<IUnitOfWork>();
                        do
                        {
                            try
                            {
                                ((dynamic)messageHandler).Handle((dynamic)message);
                                //unitOfWork.Commit();
                                messageReply = new MessageReply(commandContext.MessageID, commandContext.Reply);
                                needRetry    = false;
                            }
                            catch (Exception ex)
                            {
                                if (!(ex is OptimisticConcurrencyException) || !needRetry)
                                {
                                    throw;
                                }
                            }
                        } while (needRetry);
                    }
                }
                else
                {
                    messageReply = new MessageReply(commandContext.MessageID, new MessageDuplicatelyHandled());
                }
            }
            catch (Exception e)
            {
                messageReply = new MessageReply(commandContext.MessageID, e.GetBaseException());
                if (e is DomainException)
                {
                    _logger.Warn(message.ToJson(), e);
                }
                else
                {
                    _logger.Error(message.ToJson(), e);
                }
                if (messageStore != null)
                {
                    messageStore.SaveFailedCommand(commandContext);
                }
            }
            finally
            {
                PerMessageContextLifetimeManager.CurrentMessageContext = null;
            }
            if (!commandHasHandled)
            {
                OnMessageHandled(commandContext, messageReply);
            }
        }
        protected virtual void ConsumeMessage(IMessageContext commandContext)
        {
            var           command      = commandContext.Message as ICommand;
            IMessageReply messageReply = null;

            if (command == null)
            {
                return;
            }
            var needRetry = command.NeedRetry;

            PerMessageContextLifetimeManager.CurrentMessageContext = commandContext;
            IEnumerable <IMessageContext> eventContexts = null;
            var messageStore      = IoCFactory.Resolve <IMessageStore>();
            var eventBus          = IoCFactory.Resolve <IEventBus>();
            var commandHasHandled = messageStore.HasCommandHandled(commandContext.MessageID);

            if (commandHasHandled)
            {
                messageReply = NewReply(commandContext.MessageID, new MessageDuplicatelyHandled());
                //new MessageReply(commandContext.MessageID, new MessageDuplicatelyHandled());
            }
            else
            {
                var messageHandler = _handlerProvider.GetHandler(command.GetType());
                _logger.InfoFormat("Handle command, commandID:{0}", commandContext.MessageID);

                if (messageHandler == null)
                {
                    messageReply = NewReply(commandContext.MessageID, new NoHandlerExists());
                }
                else
                {
                    bool success = false;
                    do
                    {
                        try
                        {
                            using (var transactionScope = new TransactionScope(TransactionScopeOption.Required,
                                                                               new TransactionOptions {
                                IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
                            }))
                            {
                                ((dynamic)messageHandler).Handle((dynamic)command);
                                messageReply  = NewReply(commandContext.MessageID, commandContext.Reply);
                                eventContexts = messageStore.SaveCommand(commandContext, eventBus.GetMessages());
                                transactionScope.Complete();
                            }
                            needRetry = false;
                            success   = true;
                        }
                        catch (Exception e)
                        {
                            if (e is OptimisticConcurrencyException && needRetry)
                            {
                                eventContexts = null;
                                eventBus.ClearMessages();
                            }
                            else
                            {
                                messageReply = NewReply(commandContext.MessageID, e.GetBaseException());
                                if (e is DomainException)
                                {
                                    _logger.Warn(command.ToJson(), e);
                                }
                                else
                                {
                                    _logger.Error(command.ToJson(), e);
                                }
                                messageStore.SaveFailedCommand(commandContext, e);
                                needRetry = false;
                            }
                        }
                    } while (needRetry);
                    if (success && eventContexts != null && eventContexts.Count() > 0)
                    {
                        IoCFactory.Resolve <IEventPublisher>().Publish(eventContexts.ToArray());
                    }
                }
            }
            OnMessageHandled(commandContext, messageReply);
        }
Exemple #4
0
        protected virtual void ConsumeMessage(IMessageContext commandContext)
        {
            var             command      = commandContext.Message as ICommand;
            IMessageContext messageReply = null;

            if (command == null)
            {
                return;
            }
            var needRetry = command.NeedRetry;

            PerMessageContextLifetimeManager.CurrentMessageContext = commandContext;
            List <IMessageContext> eventContexts = new List <IMessageContext>();
            var messageStore      = IoCFactory.Resolve <IMessageStore>();
            var eventBus          = IoCFactory.Resolve <IEventBus>();
            var commandHasHandled = messageStore.HasCommandHandled(commandContext.MessageID);

            if (commandHasHandled)
            {
                messageReply = _messageQueueClient.WrapMessage(new MessageDuplicatelyHandled(), commandContext.MessageID, commandContext.ReplyToEndPoint);
                eventContexts.Add(messageReply);
            }
            else
            {
                var messageHandler = _handlerProvider.GetHandler(command.GetType());
                _logger.InfoFormat("Handle command, commandID:{0}", commandContext.MessageID);

                if (messageHandler == null)
                {
                    messageReply = _messageQueueClient.WrapMessage(new NoHandlerExists(), commandContext.MessageID, commandContext.ReplyToEndPoint);
                    eventContexts.Add(messageReply);
                }
                else
                {
                    do
                    {
                        try
                        {
                            using (var transactionScope = new TransactionScope(TransactionScopeOption.Required,
                                                                               new TransactionOptions {
                                IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
                            }))
                            {
                                ((dynamic)messageHandler).Handle((dynamic)command);
                                messageReply = _messageQueueClient.WrapMessage(commandContext.Reply, commandContext.MessageID, commandContext.ReplyToEndPoint);
                                eventContexts.Add(messageReply);
                                eventBus.GetMessages().ForEach(@event => {
                                    var eventContext = _messageQueueClient.WrapMessage(@event, commandContext.MessageID);
                                    eventContexts.Add(eventContext);
                                });

                                messageStore.SaveCommand(commandContext, eventContexts.ToArray());
                                transactionScope.Complete();
                            }
                            needRetry = false;
                        }
                        catch (Exception e)
                        {
                            eventContexts.Clear();
                            if (e is OptimisticConcurrencyException && needRetry)
                            {
                                eventBus.ClearMessages();
                            }
                            else
                            {
                                messageReply = _messageQueueClient.WrapMessage(e.GetBaseException(), commandContext.MessageID, commandContext.ReplyToEndPoint);
                                eventContexts.Add(messageReply);
                                if (e is DomainException)
                                {
                                    _logger.Warn(command.ToJson(), e);
                                }
                                else
                                {
                                    _logger.Error(command.ToJson(), e);
                                }
                                messageStore.SaveFailedCommand(commandContext, e, messageReply);
                                needRetry = false;
                            }
                        }
                    } while (needRetry);
                }
            }
            if (_messagePublisher != null && eventContexts.Count > 0)
            {
                _messagePublisher.Send(eventContexts.ToArray());
            }
        }