예제 #1
0
        private async Task invoke(Envelope envelope, DateTime now)
        {
            using (var context = new EnvelopeContext(this, envelope, _sender, _delayedJobs))
            {
                if (envelope.IsDelayed(now))
                {
                    await moveToDelayedMessageQueue(envelope, context);
                }
                else if (envelope.ResponseId.IsNotEmpty())
                {
                    completeRequestWithRequestedResponse(envelope);
                }
                else
                {
                    try
                    {
                        deserialize(envelope);
                    }
                    catch (Exception e)
                    {
                        Logger.MessageFailed(envelope, e);
                        await envelope.Callback.MoveToErrors(new ErrorReport(envelope, e));

                        return;
                    }
                    finally
                    {
                        Logger.Received(envelope);
                    }

                    await ProcessMessage(envelope, context).ConfigureAwait(false);
                }
            }
        }
예제 #2
0
        public async Task InvokeNow(Envelope envelope)
        {
            if (envelope.Message == null)
            {
                throw new ArgumentNullException(nameof(envelope.Message));
            }

            var handler = _graph.HandlerFor(envelope.Message.GetType());

            if (handler == null)
            {
                throw new ArgumentOutOfRangeException(nameof(envelope), $"No known handler for message type {envelope.Message.GetType().FullName}");
            }

            using (var context = new EnvelopeContext(this, envelope, _sender, _delayedJobs))
            {
                try
                {
                    await handler.Handle(context);

                    // TODO -- what do we do here if this fails? Compensating actions?
                    await context.SendAllQueuedOutgoingMessages();
                }
                catch (Exception e)
                {
                    Logger.LogException(e, $"Invocation of {envelope} failed!");
                    throw;
                }
            }
        }
예제 #3
0
        public async Task ProcessMessage(Envelope envelope, EnvelopeContext context)
        {
            Logger.ExecutionStarted(envelope);

            var handler = _graph.HandlerFor(envelope.Message.GetType());

            if (handler == null)
            {
                await processNoHandlerLogic(envelope, context);
            }
            else
            {
                var continuation = await executeChain(handler, context).ConfigureAwait(false);

                await continuation.Execute(envelope, context, DateTime.UtcNow).ConfigureAwait(false);
            }
        }
예제 #4
0
        private async Task <IContinuation> executeChain(MessageHandler handler, EnvelopeContext context)
        {
            try
            {
                context.Envelope.Attempts++;

                await handler.Handle(context).ConfigureAwait(false);

                Logger.ExecutionFinished(context.Envelope);

                return(MessageSucceededContinuation.Instance);
            }
            catch (Exception e)
            {
                Logger.LogException(e, context.Envelope.CorrelationId, "Failure during message processing execution");
                return(context.DetermineContinuation(e, handler.Chain, _graph));
            }
        }
예제 #5
0
        private async Task moveToDelayedMessageQueue(Envelope envelope, EnvelopeContext context)
        {
            try
            {
                envelope.Attempts++;
                _delayedJobs.Enqueue(envelope.ExecutionTime.Value, envelope);
                await envelope.Callback.MarkSuccessful();
            }
            catch (Exception e)
            {
                if (envelope.Attempts >= 3)
                {
                    await envelope.Callback.MarkFailed(e);

                    context.Logger.LogException(e, envelope.CorrelationId, "Failed to move delayed message to the delayed message queue");
                }

                var continuation = _graph.DetermineContinuation(envelope, e) ?? new MoveToErrorQueue(e);
                await continuation.Execute(envelope, context, DateTime.UtcNow);
            }
        }
예제 #6
0
        private async Task processNoHandlerLogic(Envelope envelope, EnvelopeContext context)
        {
            Logger.NoHandlerFor(envelope);

            foreach (var handler in _missingHandlers)
            {
                try
                {
                    await handler.Handle(envelope, context);
                }
                catch (Exception e)
                {
                    Logger.LogException(e);
                }
            }

            if (envelope.AckRequested)
            {
                await context.SendAcknowledgement(envelope);
            }
        }