예제 #1
0
        /// <summary>
        /// Implements persistent message delivery handler
        /// </summary>
        /// <param name="builder">Horse MQ Builder</param>
        /// <param name="deleteWhen">Decision when messages are deleted from disk</param>
        /// <param name="producerAckDecision">Decision when producer receives acknowledge</param>
        /// <param name="useRedelivery">True if want to keep redelivery data and send to consumers with message headers</param>
        /// <param name="ackTimeoutPutback">Putback decision when ack message isn't received</param>
        /// <param name="nackPutback">Putback decision when negative ack is received</param>
        /// <returns></returns>
        public static HorseMqBuilder UsePersistentDeliveryHandler(this HorseMqBuilder builder,
                                                                  DeleteWhen deleteWhen,
                                                                  ProducerAckDecision producerAckDecision,
                                                                  bool useRedelivery = false,
                                                                  PutBackDecision ackTimeoutPutback = PutBackDecision.End,
                                                                  PutBackDecision nackPutback       = PutBackDecision.End)
        {
            builder.Server.DeliveryHandlerFactory = async(dh) =>
            {
                DatabaseOptions           databaseOptions = ConfigurationFactory.Builder.CreateOptions(dh.Queue);
                PersistentDeliveryHandler handler         = new PersistentDeliveryHandler(dh.Queue, databaseOptions,
                                                                                          deleteWhen,
                                                                                          producerAckDecision,
                                                                                          useRedelivery,
                                                                                          dh.DeliveryHandlerHeader);

                handler.AckTimeoutPutBack  = ackTimeoutPutback;
                handler.NegativeAckPutBack = nackPutback;

                await handler.Initialize();

                dh.OnAfterCompleted(AfterDeliveryHandlerCreated);
                return(handler);
            };
            return(builder);
        }
예제 #2
0
        /// <summary>
        /// Creates final decision from multiple decisions.
        /// Final decision has bests choices for each decision.
        /// </summary>
        internal static Decision CreateFinalDecision(Decision final, Decision decision)
        {
            bool                        allow   = false;
            PutBackDecision             putBack = PutBackDecision.No;
            bool                        save    = false;
            DeliveryAcknowledgeDecision ack     = DeliveryAcknowledgeDecision.None;

            if (decision.Allow)
            {
                allow = true;
            }

            if (decision.PutBack != PutBackDecision.No)
            {
                putBack = decision.PutBack;
            }

            if (decision.SaveMessage)
            {
                save = true;
            }

            if (decision.Acknowledge == DeliveryAcknowledgeDecision.Always)
            {
                ack = DeliveryAcknowledgeDecision.Always;
            }

            else if (decision.Acknowledge == DeliveryAcknowledgeDecision.IfSaved && final.Acknowledge == DeliveryAcknowledgeDecision.None)
            {
                ack = DeliveryAcknowledgeDecision.IfSaved;
            }

            return(new Decision(allow, save, putBack, ack));
        }
예제 #3
0
 /// <summary>
 /// Creates new decision with full parameters
 /// </summary>
 public Decision(bool allow, bool save, PutBackDecision putBack, DeliveryAcknowledgeDecision ack, QueueAcknowledgeDeliveryHandler acknowledgeDelivery)
 {
     Allow               = allow;
     SaveMessage         = save;
     PutBack             = putBack;
     Acknowledge         = ack;
     AcknowledgeDelivery = acknowledgeDelivery;
 }
예제 #4
0
 /// <summary>
 /// Creates new decision with full parameters
 /// </summary>
 public Decision(bool allow, bool save, PutBackDecision putBack, DeliveryAcknowledgeDecision ack)
 {
     Allow               = allow;
     SaveMessage         = save;
     PutBack             = putBack;
     Acknowledge         = ack;
     AcknowledgeDelivery = null;
 }
예제 #5
0
 /// <summary>
 /// Creates new decision without keeping messages and acknowledge
 /// </summary>
 public Decision(bool allow, bool save)
 {
     Allow               = allow;
     SaveMessage         = save;
     PutBack             = PutBackDecision.No;
     Acknowledge         = DeliveryAcknowledgeDecision.None;
     AcknowledgeDelivery = null;
 }
예제 #6
0
        /// <inheritdoc />
        public virtual async Task <Decision> AcknowledgeReceived(HorseQueue queue, HorseMessage acknowledgeMessage, MessageDelivery delivery, bool success)
        {
            if (success && DeleteWhen == DeleteWhen.AfterAcknowledgeReceived)
            {
                await DeleteMessage(delivery.Message.Message.MessageId);
            }

            DeliveryAcknowledgeDecision ack = DeliveryAcknowledgeDecision.None;

            if (ProducerAckDecision == ProducerAckDecision.AfterConsumerAckReceived)
            {
                ack = success ? DeliveryAcknowledgeDecision.Always : DeliveryAcknowledgeDecision.Negative;
            }

            PutBackDecision putBack = success ? PutBackDecision.No : NegativeAckPutBack;

            return(new Decision(true, false, putBack, ack));
        }
예제 #7
0
        /// <summary>
        /// Decision: Allow.
        /// If AcknowledgeWhen is AfterAcknowledge, acknowledge is sent to producer.
        /// </summary>
        public async Task <Decision> AcknowledgeReceived(HorseQueue queue, HorseMessage acknowledgeMessage, MessageDelivery delivery, bool success)
        {
            DeliveryAcknowledgeDecision ack = DeliveryAcknowledgeDecision.None;

            if (_producerAck == AcknowledgeWhen.AfterAcknowledge)
            {
                ack = success ? DeliveryAcknowledgeDecision.Always : DeliveryAcknowledgeDecision.Negative;
            }

            PutBackDecision putBack = PutBackDecision.No;

            if (!success)
            {
                putBack = _consumerAckFail;
            }

            return(await Task.FromResult(new Decision(true, false, putBack, ack)));
        }
예제 #8
0
        /// <summary>
        /// Creates and initializes new persistent delivery handler for the queue
        /// </summary>
        /// <param name="builder">Delivery handler builder</param>
        /// <param name="deleteWhen">Decision when messages are deleted from disk</param>
        /// <param name="producerAckDecision">Decision when producer receives acknowledge</param>
        /// <param name="useRedelivery">True if want to keep redelivery data and send to consumers with message headers</param>
        /// <param name="key">Definition key for delivery handler. You can manage with that key, how the queue will be reloaded.</param>
        /// <param name="ackTimeoutPutback">Putback decision when ack message isn't received</param>
        /// <param name="nackPutback">Putback decision when negative ack is received</param>
        /// <returns></returns>
        public static async Task <IMessageDeliveryHandler> CreatePersistentDeliveryHandler(this DeliveryHandlerBuilder builder,
                                                                                           DeleteWhen deleteWhen,
                                                                                           ProducerAckDecision producerAckDecision,
                                                                                           bool useRedelivery = false,
                                                                                           PutBackDecision ackTimeoutPutback = PutBackDecision.End,
                                                                                           PutBackDecision nackPutback       = PutBackDecision.End,
                                                                                           string key = "default")
        {
            DatabaseOptions           databaseOptions = ConfigurationFactory.Builder.CreateOptions(builder.Queue);
            PersistentDeliveryHandler handler         = new PersistentDeliveryHandler(builder.Queue, databaseOptions, deleteWhen, producerAckDecision, useRedelivery, key);

            handler.AckTimeoutPutBack  = ackTimeoutPutback;
            handler.NegativeAckPutBack = nackPutback;
            await handler.Initialize();

            builder.OnAfterCompleted(AfterDeliveryHandlerCreated);
            return(handler);
        }
예제 #9
0
 /// <summary>
 /// Quick IMessageDeliveryHandler implementation with acknowledge features.
 /// </summary>
 /// <param name="producerAck">Decision, when producer will receive acknowledge (or confirm)</param>
 /// <param name="consumerAckFail">Decision, what will be done if consumer sends nack or doesn't send ack in time</param>
 public AckDeliveryHandler(AcknowledgeWhen producerAck, PutBackDecision consumerAckFail)
 {
     _producerAck     = producerAck;
     _consumerAckFail = consumerAckFail;
 }
예제 #10
0
 /// <summary>
 /// Implements non-durable basic delivery handler with ack
 /// </summary>
 /// <param name="builder">Horse MQ Builder</param>
 /// <param name="producerAck">Decision, when producer will receive acknowledge (or confirm)</param>
 /// <param name="consumerAckFail">Decision, what will be done if consumer sends nack or doesn't send ack in time</param>
 public static HorseMqBuilder UseAckDeliveryHandler(this HorseMqBuilder builder, AcknowledgeWhen producerAck, PutBackDecision consumerAckFail)
 {
     builder.Server.DeliveryHandlerFactory = d => Task.FromResult <IMessageDeliveryHandler>(new AckDeliveryHandler(producerAck, consumerAckFail));
     return(builder);
 }