/// <inheritdoc /> public virtual async Task <Decision> BeginSend(HorseQueue queue, QueueMessage message) { if (UseRedelivery) { message.DeliveryCount++; await RedeliveryService.Set(message.Message.MessageId, message.DeliveryCount); if (message.DeliveryCount > 1) { message.Message.SetOrAddHeader(HorseHeaders.DELIVERY, message.DeliveryCount.ToString()); } } return(new Decision(true, true, PutBackDecision.No, DeliveryAcknowledgeDecision.None)); }
/// <summary> /// Deletes message from database /// </summary> protected virtual async Task DeleteMessage(string id) { if (UseRedelivery) { await RedeliveryService.Remove(id); } for (int i = 0; i < 3; i++) { bool deleted = await Database.Delete(id); if (deleted) { return; } await Task.Delay(3); } }
/// <summary> /// Removes queue from configuration and deletes all database files /// </summary> private async void Destroy(HorseQueue queue) { if (UseRedelivery) { await RedeliveryService.Close(); RedeliveryService.Delete(); } try { ConfigurationFactory.Manager.Remove(queue); ConfigurationFactory.Manager.Save(); await Database.Close(); for (int i = 0; i < 5; i++) { bool deleted = await Database.File.Delete(); if (deleted) { break; } await Task.Delay(3); } } catch (Exception e) { if (ConfigurationFactory.Builder.ErrorAction != null) { ConfigurationFactory.Builder.ErrorAction(queue, null, e); } } }
/// <summary> /// Initializes queue, opens database files and fills messages into the queue /// </summary> public virtual async Task Initialize() { if (Queue.Options.Acknowledge == QueueAckDecision.None) { if (DeleteWhen == DeleteWhen.AfterAcknowledgeReceived) { throw new NotSupportedException("Delete option is AfterAcknowledgeReceived but queue Acknowledge option is None. " + "Messages are not deleted from disk with this configuration. " + "Please change queue Acknowledge option or DeleteWhen option"); } if (ProducerAckDecision == ProducerAckDecision.AfterConsumerAckReceived) { throw new NotSupportedException("Producer Ack option is AfterConsumerAckReceived but queue Acknowledge option is None. " + "Messages are not deleted from disk with this configuration. " + "Please change queue Acknowledge option or ProducerAckDecision option"); } } await Database.Open(); Queue.OnDestroyed += Destroy; List <KeyValuePair <string, int> > deliveries = null; if (UseRedelivery) { RedeliveryService = new RedeliveryService(Database.File.Filename + ".delivery"); await RedeliveryService.Load(); deliveries = RedeliveryService.GetDeliveries(); } var dict = await Database.List(); if (dict.Count > 0) { QueueFiller filler = new QueueFiller(Queue); PushResult result = filler.FillMessage(dict.Values, true, qm => { if (!UseRedelivery || deliveries == null || deliveries.Count == 0 || string.IsNullOrEmpty(qm.Message.MessageId)) { return; } var kv = deliveries.FirstOrDefault(x => x.Key == qm.Message.MessageId); if (kv.Value > 0) { qm.DeliveryCount = kv.Value; } }); if (result != PushResult.Success) { throw new InvalidOperationException($"Cannot fill messages into {Queue.Name} queue : {result}"); } } }