示例#1
0
        public void OnCreate(Connection.IConnection connection)
        {
            _logger?.LogDebug("OnCreate for connection: {connection}", connection?.ToString());

            if (Interlocked.CompareExchange(ref _initializing, 1, 0) != 0)
            {
                return;
            }

            try
            {
                /*
                 * ...but it is possible for this to happen twice in the same ConnectionFactory (if more than
                 * one concurrent Connection is allowed). It's idempotent, so no big deal (a bit of network
                 * chatter). In fact it might even be a good thing: exclusive queues only make sense if they are
                 * declared for every connection. If anyone has a problem with it: use auto-startup="false".
                 */
                if (RetryTemplate != null && !RetryDisabled)
                {
                    RetryTemplate.Execute(
                        c =>
                    {
                        Initialize();
                    });
                }
                else
                {
                    Initialize();
                }
            }
            finally
            {
                Interlocked.CompareExchange(ref _initializing, 0, 1);
            }
        }
示例#2
0
        public StatefulRetryOperationsInterceptor() : base()
        {
            var retryTemplate = new RetryTemplate();

            retryTemplate.RetryPolicy = new NeverRetryPolicy();
            retryOperations           = retryTemplate;
        }
        protected void SendResponse(RC.IModel channel, Address replyTo, IMessage <byte[]> messageIn)
        {
            var message = messageIn;

            if (BeforeSendReplyPostProcessors != null)
            {
                var      processors    = BeforeSendReplyPostProcessors;
                IMessage postProcessed = message;
                foreach (var postProcessor in processors)
                {
                    postProcessed = postProcessor.PostProcessMessage(postProcessed);
                }

                message = postProcessed as IMessage <byte[]>;
                if (message == null)
                {
                    throw new InvalidOperationException("A BeforeSendReplyPostProcessors failed to return IMessage<byte[]>");
                }
            }

            PostProcessChannel(channel, message);

            try
            {
                _logger?.LogDebug("Publishing response to exchange = [{exchange}], routingKey = [{routingKey}]", replyTo.ExchangeName, replyTo.RoutingKey);
                if (RetryTemplate == null)
                {
                    DoPublish(channel, replyTo, message);
                }
                else
                {
                    var messageToSend = message;
                    RetryTemplate.Execute <object>(
                        ctx =>
                    {
                        DoPublish(channel, replyTo, messageToSend);
                        return(null);
                    },
                        ctx =>
                    {
                        if (RecoveryCallback != null)
                        {
                            ctx.SetAttribute(SendRetryContextAccessor.MESSAGE, messageToSend);
                            ctx.SetAttribute(SendRetryContextAccessor.ADDRESS, replyTo);
                            RecoveryCallback.Recover(ctx);
                            return(null);
                        }
                        else
                        {
                            throw RabbitExceptionTranslator.ConvertRabbitAccessException(ctx.LastException);
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                throw RabbitExceptionTranslator.ConvertRabbitAccessException(ex);
            }
        }
示例#4
0
        protected void SendResponse(IModel channel, Address replyTo, Message messageIn)
        {
            var message = messageIn;

            if (BeforeSendReplyPostProcessors != null)
            {
                var processors = BeforeSendReplyPostProcessors;
                foreach (var postProcessor in processors)
                {
                    message = postProcessor.PostProcessMessage(message);
                }
            }

            PostProcessChannel(channel, message);

            try
            {
                _logger?.LogDebug("Publishing response to exchange = [" + replyTo.ExchangeName + "], routingKey = [" + replyTo.RoutingKey + "]");
                if (RetryTemplate == null)
                {
                    DoPublish(channel, replyTo, message);
                }
                else
                {
                    var messageToSend = message;
                    RetryTemplate.Execute <object>(
                        ctx =>
                    {
                        DoPublish(channel, replyTo, messageToSend);
                        return(null);
                    },
                        ctx =>
                    {
                        if (RecoveryCallback != null)
                        {
                            ctx.SetAttribute(SendRetryContextAccessor.MESSAGE, messageToSend);
                            ctx.SetAttribute(SendRetryContextAccessor.ADDRESS, replyTo);
                            RecoveryCallback.Recover(ctx);
                            return(null);
                        }
                        else
                        {
                            throw RabbitExceptionTranslator.ConvertRabbitAccessException(ctx.LastException);
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                throw RabbitExceptionTranslator.ConvertRabbitAccessException(ex);
            }
        }
示例#5
0
            public void Init()
            {
                if (RetryTemplate != null && ErrorChannel != null)
                {
                    throw new InvalidOperationException(
                              "Cannot have an 'errorChannel' property when a 'RetryTemplate' is "
                              + "provided; use an 'ErrorMessageSendingRecoverer' in the 'recoveryCallback' property to "
                              + "send an error message when retries are exhausted");
                }

                var messageListener = new Listener(this);

                if (RetryTemplate != null)
                {
                    RetryTemplate.RegisterListener(messageListener);
                }

                _messageListenerContainer.MessageListener = (m) => messageListener.Accept(m);
            }
示例#6
0
        public override bool Poll(IMessageHandler handler, Type type)
        {
            var message = Receive(type);

            if (message == null)
            {
                return(false);
            }

            var ackCallback = StaticMessageHeaderAccessor.GetAcknowledgmentCallback(message);

            try
            {
                if (RetryTemplate == null)
                {
                    Handle(message, handler);
                }
                else
                {
                    RetryTemplate.Execute((ctx) => Handle(message, handler), _recoveryCallback);
                }

                return(true);
            }
            catch (MessagingException e)
            {
                if (RetryTemplate == null && !ShouldRequeue(e))
                {
                    _messagingTemplate.Send(ErrorChannel, ErrorMessageStrategy.BuildErrorMessage(e, _attributesHolder.Value));
                    return(true);
                }
                else if (!ackCallback.IsAcknowledged && ShouldRequeue(e))
                {
                    AckUtils.Requeue(ackCallback);
                    return(true);
                }
                else
                {
                    AckUtils.AutoNack(ackCallback);
                }

                if (e.FailedMessage.Equals(message))
                {
                    throw;
                }

                throw new MessageHandlingException(message, e);
            }
            catch (Exception e)
            {
                AckUtils.AutoNack(ackCallback);
                if (e is MessageHandlingException && ((MessageHandlingException)e).FailedMessage.Equals(message))
                {
                    throw;
                }

                throw new MessageHandlingException(message, e);
            }
            finally
            {
                AckUtils.AutoAck(ackCallback);
            }
        }