Example #1
0
        /// <summary>
        /// Triggers event and sends message to subscribers
        /// </summary>
        protected void Trigger(object model)
        {
            try
            {
                if (_subscribers.Count == 0)
                {
                    return;
                }

                HorseMessage message = new HorseMessage(MessageType.Event, Target);
                message.SetSource(Name);

                if (model != null)
                {
                    message.Serialize(model, _server.MessageContentSerializer);
                }

                byte[] data = HmqWriter.Create(message);

                List <MqClient> removing = null;

                lock (_subscribers)
                    foreach (MqClient subscriber in _subscribers)
                    {
                        //if client is disconnected, add it into removing list
                        if (!subscriber.IsConnected)
                        {
                            //removing list is created when it's needed
                            if (removing == null)
                            {
                                removing = new List <MqClient>();
                            }

                            removing.Add(subscriber);
                        }
                        else
                        {
                            _ = subscriber.SendAsync(data);
                        }
                    }

                //if there are some removing clients from subscribers list, remove them
                if (removing != null)
                {
                    lock (_subscribers)
                        foreach (MqClient remove in removing)
                        {
                            _subscribers.Remove(remove);
                        }
                }
            }
            catch (Exception e)
            {
                _server.SendError("EVENT_TRIGGER", e, $"Name:{Name}, Type:{GetType().Name}");
            }
        }
Example #2
0
        /// <summary>
        /// Called when a acknowledge message is received from the client
        /// </summary>
        internal async Task AcknowledgeDelivered(MqClient from, HorseMessage deliveryMessage)
        {
            try
            {
                if (!IsInitialized)
                {
                    return;
                }

                MessageDelivery delivery = TimeKeeper.FindAndRemoveDelivery(from, deliveryMessage.MessageId);

                //when server and consumer are in pc,
                //sometimes consumer sends ack before server start to follow ack of the message
                //that happens when ack message is arrived in less than 0.01ms
                //in that situation, server can't find the delivery with FindAndRemoveDelivery, it returns null
                //so we need to check it again after a few milliseconds
                if (delivery == null)
                {
                    await Task.Delay(1);

                    delivery = TimeKeeper.FindAndRemoveDelivery(from, deliveryMessage.MessageId);

                    //try again
                    if (delivery == null)
                    {
                        await Task.Delay(3);

                        delivery = TimeKeeper.FindAndRemoveDelivery(from, deliveryMessage.MessageId);
                    }
                }

                bool success = !(deliveryMessage.HasHeader &&
                                 deliveryMessage.Headers.Any(x => x.Key.Equals(HorseHeaders.NEGATIVE_ACKNOWLEDGE_REASON, StringComparison.InvariantCultureIgnoreCase)));

                // ReSharper disable once ConditionIsAlwaysTrueOrFalse (it's possible, resharper doesn't work properly in here)
                if (delivery != null)
                {
                    if (delivery.Receiver != null && delivery.Message == delivery.Receiver.CurrentlyProcessing)
                    {
                        delivery.Receiver.CurrentlyProcessing = null;
                    }

                    delivery.MarkAsAcknowledged(success);
                }

                if (success)
                {
                    Info.AddAcknowledge();
                }
                else
                {
                    Info.AddNegativeAcknowledge();
                }

                Decision decision = await DeliveryHandler.AcknowledgeReceived(this, deliveryMessage, delivery, success);

                // ReSharper disable once ConditionIsAlwaysTrueOrFalse (it's possible, resharper doesn't work properly in here)
                if (delivery != null)
                {
                    if (Options.HideClientNames)
                    {
                        deliveryMessage.SetSource(null);
                    }

                    await ApplyDecision(decision, delivery.Message, deliveryMessage);
                }

                ReleaseAcknowledgeLock(true);
            }
            catch (Exception e)
            {
                Server.SendError("QUEUE_ACK_RECEIVED", e, $"QueueName:{Name}, MessageId:{deliveryMessage.MessageId}");
            }
        }