Example #1
0
        /// <summary>
        /// Finds and subscribes to the queue and sends response
        /// </summary>
        private async Task Subscribe(MqClient client, HorseMessage message)
        {
            HorseQueue queue = _server.FindQueue(message.Target);

            //if auto creation active, try to create queue
            if (queue == null && _server.Options.AutoQueueCreation)
            {
                QueueOptions options = QueueOptions.CloneFrom(_server.Options);
                queue = await _server.CreateQueue(message.Target, options, message, _server.DeliveryHandlerFactory, true, true);
            }

            if (queue == null)
            {
                if (message.WaitResponse)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.NotFound));
                }

                return;
            }

            QueueClient found = queue.FindClient(client.UniqueId);

            if (found != null)
            {
                if (message.WaitResponse)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));
                }

                return;
            }

            QueueSubscriptionResult result = await queue.AddClient(client);

            if (message.WaitResponse)
            {
                switch (result)
                {
                case QueueSubscriptionResult.Success:
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));

                    break;

                case QueueSubscriptionResult.Unauthorized:
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Unauthorized));

                    break;

                case QueueSubscriptionResult.Full:
                    await client.SendAsync(message.CreateResponse(HorseResultCode.LimitExceeded));

                    break;
                }
            }
        }
        public async Task Handle(MqClient client, HorseMessage message, bool fromNode)
        {
            try
            {
                HorseQueue queue = _server.FindQueue(message.Target);

                //if auto creation active, try to create queue
                if (queue == null && _server.Options.AutoQueueCreation)
                {
                    QueueOptions options = QueueOptions.CloneFrom(_server.Options);
                    queue = await _server.CreateQueue(message.Target, options, message, _server.DeliveryHandlerFactory, true, true);
                }

                if (queue == null)
                {
                    if (!string.IsNullOrEmpty(message.MessageId))
                    {
                        await client.SendAsync(message.CreateResponse(HorseResultCode.NotFound));
                    }

                    return;
                }

                await HandlePullRequest(client, message, queue);
            }
            catch (Exception e)
            {
                _server.SendError("PULL_REQUEST", e, $"QueueName:{message.Target}");
            }
        }
Example #3
0
 /// <summary>
 /// Creates and returns persistent queue
 /// </summary>
 internal static async Task <HorseQueue> CreateQueue(HorseMq mq,
                                                     string queueName,
                                                     QueueOptions options,
                                                     Func <DatabaseOptions, IPersistentDeliveryHandler> factory)
 {
     return(await mq.CreateQueue(queueName, options, async builder =>
     {
         DatabaseOptions databaseOptions = ConfigurationFactory.Builder.CreateOptions(builder.Queue);
         IPersistentDeliveryHandler handler = factory(databaseOptions);
         await handler.Initialize();
         return handler;
     }));
 }
Example #4
0
 /// <summary>
 /// Creates and returns persistent queue
 /// </summary>
 internal static async Task <HorseQueue> CreateQueue(HorseMq mq,
                                                     string queueName,
                                                     DeleteWhen deleteWhen,
                                                     ProducerAckDecision producerAckDecision,
                                                     QueueOptions options)
 {
     return(await mq.CreateQueue(queueName, options, async builder =>
     {
         DatabaseOptions databaseOptions = ConfigurationFactory.Builder.CreateOptions(builder.Queue);
         PersistentDeliveryHandler handler = new PersistentDeliveryHandler(builder.Queue, databaseOptions, deleteWhen, producerAckDecision);
         await handler.Initialize();
         return handler;
     }));
 }
        /// <summary>
        /// Loads messages of queues in configuration
        /// </summary>
        public async Task LoadQueues(HorseMq server)
        {
            foreach (QueueConfiguration queueConfiguration in Config.Queues)
            {
                HorseQueue queue = server.FindQueue(queueConfiguration.Name);
                if (queue == null)
                {
                    if (server.DeliveryHandlerFactory != null)
                    {
                        queue = await server.CreateQueue(queueConfiguration.Name,
                                                         queueConfiguration.Configuration.ToOptions(),
                                                         async builder =>
                        {
                            builder.DeliveryHandlerHeader   = queueConfiguration.DeliveryHandler;
                            IMessageDeliveryHandler handler = await server.DeliveryHandlerFactory(builder);
                            builder.OnAfterCompleted(b => { });                                  //don't trigger created events, it's already created and reloading
                            return(handler);
                        });
                    }
                    else
                    {
                        queue = await Extensions.CreateQueue(server,
                                                             queueConfiguration.Name,
                                                             (DeleteWhen)queueConfiguration.DeleteWhen,
                                                             (ProducerAckDecision)queueConfiguration.ProducerAck,
                                                             queueConfiguration.Configuration.ToOptions());
                    }

                    //queue creation not permitted, skip
                    if (queue == null)
                    {
                        continue;
                    }
                }
                else
                {
                    if (queue.DeliveryHandler is IPersistentDeliveryHandler deliveryHandler)
                    {
                        await deliveryHandler.Initialize();
                    }
                }

                queueConfiguration.Queue = queue;
            }
        }
Example #6
0
        private async Task <HorseQueue> FindQueue(MqClient client, string name, HorseMessage message)
        {
            HorseQueue queue = _server.FindQueue(name);

            //if auto creation active, try to create queue
            if (queue == null && _server.Options.AutoQueueCreation)
            {
                QueueOptions options = QueueOptions.CloneFrom(_server.Options);
                queue = await _server.CreateQueue(name, options, message, _server.DeliveryHandlerFactory, true, true);
            }

            if (queue == null)
            {
                if (client != null && message != null && !string.IsNullOrEmpty(message.MessageId))
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.NotFound));
                }

                return(null);
            }

            return(queue);
        }
        public async Task InPersistentHandler()
        {
            ConfigurationFactory.Destroy();
            PersistentDeliveryHandler handler = null;
            HorseServer server = new HorseServer();
            HorseMq     mq     = server.UseHorseMq(cfg => cfg
                                                   .AddPersistentQueues(q => q.KeepLastBackup())
                                                   .UseDeliveryHandler(async builder =>
            {
                DatabaseOptions options = new DatabaseOptions
                {
                    Filename             = "redelivery-test.tdb",
                    InstantFlush         = true,
                    CreateBackupOnShrink = false,
                    ShrinkInterval       = TimeSpan.FromSeconds(60)
                };

                handler = new PersistentDeliveryHandler(builder.Queue,
                                                        options,
                                                        DeleteWhen.AfterSend,
                                                        ProducerAckDecision.None,
                                                        true);
                await handler.Initialize();
                return(handler);
            }));

            HorseQueue queue = await mq.CreateQueue("test");

            HorseMessage message = new HorseMessage(MessageType.QueueMessage, "test");

            message.SetMessageId("id");
            message.SetStringContent("Hello, World!");
            QueueMessage queueMessage = new QueueMessage(message);

            await handler.BeginSend(queue, queueMessage);

            List <KeyValuePair <string, int> > deliveries = handler.RedeliveryService.GetDeliveries();

            Assert.Single(deliveries);
            Assert.Equal("id", deliveries[0].Key);
            Assert.Equal(1, deliveries[0].Value);

            string header = message.FindHeader(HorseHeaders.DELIVERY);

            Assert.Null(header);

            await handler.BeginSend(queue, queueMessage);

            deliveries = handler.RedeliveryService.GetDeliveries();
            Assert.Single(deliveries);
            Assert.Equal("id", deliveries[0].Key);
            Assert.Equal(2, deliveries[0].Value);

            header = message.FindHeader(HorseHeaders.DELIVERY);
            Assert.NotNull(header);
            Assert.Equal(2, Convert.ToInt32(header));

            queueMessage.MarkAsSent();

            await handler.EndSend(queue, queueMessage);

            deliveries = handler.RedeliveryService.GetDeliveries();
            Assert.Empty(deliveries);
        }
Example #8
0
        public async Task ReloadAfterRestart()
        {
            await Task.Delay(500);

            ConfigurationFactory.Destroy();
            RedeliveryService service = new RedeliveryService("data/reload-test.tdb.delivery");
            await service.Load();

            await service.Clear();

            await service.Set("id", 4);

            await service.Close();

            if (System.IO.File.Exists("data/config.json"))
            {
                System.IO.File.Delete("data/config.json");
            }

            if (System.IO.File.Exists("data/reload-test.tdb"))
            {
                System.IO.File.Delete("data/reload-test.tdb");
            }

            if (System.IO.File.Exists("data/reload-test.tdb.delivery"))
            {
                System.IO.File.Delete("data/reload-test.tdb.delivery");
            }

            HorseServer server = new HorseServer();
            PersistentDeliveryHandler handler = null;
            Func <DeliveryHandlerBuilder, Task <IMessageDeliveryHandler> > fac = async builder =>
            {
                DatabaseOptions options = new DatabaseOptions
                {
                    Filename             = "data/reload-test.tdb",
                    InstantFlush         = true,
                    CreateBackupOnShrink = false,
                    ShrinkInterval       = TimeSpan.FromSeconds(60)
                };

                handler = (PersistentDeliveryHandler)await builder.CreatePersistentDeliveryHandler(o =>
                {
                    return(new PersistentDeliveryHandler(builder.Queue,
                                                         options,
                                                         DeleteWhen.AfterSend,
                                                         ProducerAckDecision.None,
                                                         true));
                });

                return(handler);
            };

            HorseMq mq = server.UseHorseMq(cfg => cfg
                                           .AddPersistentQueues(q => q.KeepLastBackup())
                                           .UseDeliveryHandler(fac));

            HorseQueue queue = await mq.CreateQueue("reload-test",
                                                    o => o.Status = QueueStatus.Push);

            HorseMessage msg = new HorseMessage(MessageType.QueueMessage, "reload-test");

            msg.SetMessageId("id");
            msg.SetStringContent("Hello, World!");
            await queue.Push(msg);

            QueueMessage queueMsg = queue.Messages.FirstOrDefault();
            await handler.BeginSend(queue, queueMsg);

            await handler.RedeliveryService.Close();

            ConfigurationFactory.Destroy();

            mq = server.UseHorseMq(cfg => cfg
                                   .AddPersistentQueues(q => q.KeepLastBackup())
                                   .UseDeliveryHandler(fac));

            await mq.LoadPersistentQueues();

            HorseQueue queue2 = mq.FindQueue("reload-test");

            Assert.NotNull(queue2);
            Assert.NotEmpty(queue2.Messages);
            QueueMessage loadedMsg = queue2.Messages.FirstOrDefault();

            Assert.NotNull(loadedMsg);
            Assert.Equal(1, loadedMsg.DeliveryCount);
        }