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}"); } }
/// <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; } } }
/// <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; } }
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 Handle(MqClient sender, HorseMessage message, bool fromNode) { //priority has no role in ack message. //we are using priority for helping receiver type recognization for better performance if (message.HighPriority) { //target should be client MqClient target = _server.FindClient(message.Target); if (target != null) { await target.SendAsync(message); return; } } //find queue HorseQueue queue = _server.FindQueue(message.Target); if (queue != null) { await queue.AcknowledgeDelivered(sender, message); return; } //if high prio, dont try to find client again if (!message.HighPriority) { //target should be client MqClient target = _server.FindClient(message.Target); if (target != null) { await target.SendAsync(message); } } }
public Task Handle(MqClient client, HorseMessage message, bool fromNode) { string eventName = message.Target; string queueName = message.FindHeader(HorseHeaders.QUEUE_NAME); bool subscribe = message.ContentType == 1; HorseQueue queue = !string.IsNullOrEmpty(queueName) ? _server.FindQueue(queueName) : null; if (subscribe) { foreach (IClientAuthorization authorization in _server.Authorizations) { if (!authorization.CanSubscribeEvent(client, queue)) { return(SendResponse(client, message, false)); } } } switch (eventName) { case EventNames.MessageProduced: if (queue == null) { return(SendResponse(client, message, false)); } if (subscribe) { queue.OnMessageProduced.Subscribe(client); } else { queue.OnMessageProduced.Unsubscribe(client); } return(SendResponse(client, message, true)); case EventNames.ClientConnected: if (subscribe) { _server.OnClientConnected.Subscribe(client); } else { _server.OnClientConnected.Unsubscribe(client); } return(SendResponse(client, message, true)); case EventNames.ClientDisconnected: if (subscribe) { _server.OnClientDisconnected.Subscribe(client); } else { _server.OnClientDisconnected.Unsubscribe(client); } return(SendResponse(client, message, true)); case EventNames.Subscribe: if (queue == null) { return(SendResponse(client, message, false)); } if (subscribe) { queue.OnConsumerSubscribed.Subscribe(client); } else { queue.OnConsumerSubscribed.Unsubscribe(client); } return(SendResponse(client, message, true)); case EventNames.Unsubscribe: if (queue == null) { return(SendResponse(client, message, false)); } if (subscribe) { queue.OnConsumerUnsubscribed.Subscribe(client); } else { queue.OnConsumerUnsubscribed.Unsubscribe(client); } return(SendResponse(client, message, true)); case EventNames.QueueCreated: if (subscribe) { _server.OnQueueCreated.Subscribe(client); } else { _server.OnQueueCreated.Unsubscribe(client); } return(SendResponse(client, message, true)); case EventNames.QueueUpdated: if (subscribe) { _server.OnQueueUpdated.Subscribe(client); } else { _server.OnQueueUpdated.Unsubscribe(client); } return(SendResponse(client, message, true)); case EventNames.QueueRemoved: if (subscribe) { _server.OnQueueRemoved.Subscribe(client); } else { _server.OnQueueRemoved.Unsubscribe(client); } return(SendResponse(client, message, true)); } return(Task.CompletedTask); }
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); }