예제 #1
0
        public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage
        {
            //Is this a saga

            var processor = pipelineInformation.HostConfiguration.DependencyInjection.GetInstance <IProcessMessage <T> >(pipelineInformation.ProcessorInterfaceType);

            if (processor is ISaga saga)
            {
                var sagaType     = ReflectionHelper.GetAllInterfacesImplementingOpenGenericInterface(processor.GetType(), typeof(ISaga <>)).Single();
                var sagaDataType = sagaType.GenericTypeArguments[0];

                var sagaHandlerType = typeof(SagaHandler <,>).MakeGenericType(sagaDataType, typeof(T));
                var sagaHandler     = (ISagaHandler)Activator.CreateInstance(sagaHandlerType, _sagaStore, processor, await messageStateHandler.GetMessageAsync().ConfigureAwait(false));
                try
                {
                    await sagaHandler.Initialize().ConfigureAwait(false);
                }
                catch (SagaAlreadyStartedException e)
                {
                    pipelineInformation.HostConfiguration.Log.Information(e, "Saga already started");
                    await messageStateHandler.CompleteAsync().ConfigureAwait(false);

                    return;
                }

                try
                {
                    await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception)
                {
                    if (saga.MessageMapper.IsStartMessage(typeof(T)))
                    {
                        //If we have started a saga but the start message fails then we must make sure the message can be retried
                        await _sagaStore.Complete(saga.PartitionKey, saga.Id).ConfigureAwait(false);
                    }
                    throw;
                }
            }
            else
            {
                await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false);
            }
        }
예제 #2
0
 public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage
 {
     using (AsyncScopedLifestyle.BeginScope(_container))
     {
         await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false);
     }
 }
예제 #3
0
 public MiddlewareWrapper(IMessageProcessorMiddleware current, IPipelineInformation pipelineInformation, IMessageProcessor next)
 {
     _current             = current;
     _pipelineInformation = pipelineInformation;
     _next = next;
 }
예제 #4
0
        public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage
        {
            T message = null;

            try
            {
                message = await messageStateHandler.GetMessageAsync().ConfigureAwait(false);

                await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                _log.Error(e, "Error processing message {@" + typeof(T).Name + "}", message);
                try
                {
                    await messageStateHandler.AbandonByErrorAsync(e).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    _log.Error(exception, "Failed to abandon message {@" + typeof(T).Name + "}", message);
                }
            }
        }
        public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage
        {
            using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                if (messageStateHandler is IMessageLockHandler <T> lockHandler && pipelineInformation.ProcessingSettings is IExtendMessageLockTimeout extendLock)
                {
                    var token = cts.Token;
#pragma warning disable 4014
                    Task.Run(async() =>
                    {
                        await RenewLock(extendLock.ExtensionInterval, extendLock.ExtensionDuration, token, lockHandler, pipelineInformation.HostConfiguration.Log).ConfigureAwait(false);
                    }, cancellationToken).ConfigureAwait(false);
#pragma warning restore 4014
                }

                try
                {
                    await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false);
                }
                finally
                {
                    //Stop the lock renewal
                    cts.Cancel();
                }
            }
        }
 public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage
 {
     using (var scope = messageStateHandler.MessageScope.GetScope())
     {
         messageStateHandler.MessageScope = scope;
         await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false);
     }
 }
예제 #7
0
        public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage
        {
            var messageName = typeof(T).FullName;

            using (var operation = _client.StartOperation <RequestTelemetry>(messageName))
            {
                try
                {
                    await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false);

                    // Add the message properties to the telemetry log
                    foreach (var property in messageStateHandler.MessageProperties)
                    {
                        operation.Telemetry.Properties[property.Key] = property.Value;
                    }

                    operation.Telemetry.Success = true;
                }
                catch (Exception e)
                {
                    operation.Telemetry.Success = false;
                    _client.TrackException(e);
                    throw;
                }
            }
        }
예제 #8
0
            public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage
            {
                if (!_stopwatch.IsRunning)
                {
                    _stopwatch.Start();
                }
                await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false);

                if (++_count % 1000 == 0)
                {
                    Console.WriteLine($"Processed {_count} messages in {_stopwatch.Elapsed} {_count / _stopwatch.Elapsed.TotalSeconds} m/s");
                }
            }
예제 #9
0
 public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage
 {
     using (_serviceProvider.CreateScope())
     {
         await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false);
     }
 }
예제 #10
0
        public async Task ProcessAsync <T>(IMessageStateHandler <T> messageStateHandler, IPipelineInformation pipelineInformation, IMessageProcessor next, CancellationToken cancellationToken) where T : class, IMessage
        {
            if (messageStateHandler.DeliveryCount > messageStateHandler.DeadLetterDeliveryLimit)
            {
                var processor = messageStateHandler.MessageScope.GetInstance <IProcessMessage <T> >(pipelineInformation.ProcessorInterfaceType);

                if (processor is IProcessBeforeDeadLetter <T> deadletterProcessor)
                {
                    var message = await messageStateHandler.GetMessageAsync().ConfigureAwait(false);

                    try
                    {
                        await deadletterProcessor.BeforeDeadLetterAsync(message, cancellationToken).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        pipelineInformation.HostConfiguration.Log.Error(e, "Failed before deadletter processing {@" + typeof(T).Name + "}", message);
                    }
                }

                await messageStateHandler.DeadLetterAsync(messageStateHandler.DeadLetterDeliveryLimit).ConfigureAwait(false);

                return;
            }
            await next.ProcessAsync(messageStateHandler, cancellationToken).ConfigureAwait(false);
        }