private async Task sendMessages(Endpoint destination, PersistentMessage[] messages) { var sender = createSender(destination, messages); MessageBookmark[] sendHistoryBookmarks = null; sender.Success = () => sendHistoryBookmarks = success(messages); try { await sender.Send(); _logger.DebugMessage(() => new MessagesSent(messages, destination)); } catch (FailedToConnectException ex) { _logger.InfoMessage(new FailedToSend(destination, "Failed to connect", ex)); failedToConnect(messages); } catch (QueueDoesNotExistsException) { _logger.InfoMessage(new FailedToSend(destination, "Queue doesn't exist")); failedToSend(messages, true); } catch (RevertSendException) { _logger.InfoMessage(new FailedToSend(destination, "Revert was received")); revert(sendHistoryBookmarks, messages); } catch (Exception ex) { _logger.InfoMessage(new FailedToSend(destination, "Exception was thrown", ex)); failedToSend(messages); } }
public void OneMessage() { Message[] recievedMsgs = null; var endPoint = new Endpoint("localhost", 23456); using (var reciever = new Receiver(new IPEndPoint(IPAddress.Loopback, 23456), messages => { recievedMsgs = messages; return MockRepository.GenerateStub<IMessageAcceptance>(); }, ObjectMother.Logger())) { reciever.Start(); new Sender(ObjectMother.Logger()) { Destination = endPoint, Messages = new[] { new Message { Data = new byte[] {1, 2, 4, 5, 6}, SentAt = new DateTime(2001, 1, 1), Queue = "hello doggy", Id = MessageId.GenerateRandom() }, } }.Send(); Wait.Until(() => recievedMsgs != null).ShouldBeTrue(); recievedMsgs.ShouldHaveCount(1); "hello doggy".ShouldEqual(recievedMsgs[0].Queue); new byte[] { 1, 2, 4, 5, 6 }.ShouldEqual(recievedMsgs[0].Data); new DateTime(2001, 1, 1).ShouldEqual(recievedMsgs[0].SentAt); } }
public IEnumerable<Endpoint> GetEndpointsToSend(IEnumerable<Endpoint> currentlySending, int numberOfEndpoints) { var endpoints = new HashSet<Endpoint>(); var enumerator = outgoing.GetEnumerator(); while (enumerator.MoveNext()) { var endpoint = new Endpoint( outgoing.ForColumnType<StringColumn>().Get("address"), outgoing.ForColumnType<IntColumn>().Get("port")); if (!endpoints.Contains(endpoint) && !currentlySending.Contains(endpoint)) { endpoints.Add(endpoint); if (endpoints.Count == numberOfEndpoints) break; } } return endpoints; }
private async Task sendMessages(Endpoint destination, PersistentMessage[] messages) { var sender = createSender(destination, messages); MessageBookmark[] sendHistoryBookmarks = null; sender.Success = () => sendHistoryBookmarks = success(messages); try { await sender.Send().ConfigureAwait(false); _logger.MessagesSent(messages, destination); } catch (FailedToConnectException ex) { _logger.FailedToSend(destination, "Failed to connect", ex); failedToConnect(messages); } catch (QueueDoesNotExistsException) { _logger.FailedToSend(destination, "Queue doesn't exist"); failedToSend(messages, true); } catch (RevertSendException) { _logger.FailedToSend(destination, "Revert was received"); revert(sendHistoryBookmarks, messages); } catch (TimeoutException) { try { _logger.FailedToSend(destination, "Timed out"); failedToSend(messages); } catch (EsentException) { // This will occur if the task completed as the TimeoutException was thrown, and // the message was moved to history. Swallow it to prevent unobserved task exceptions. } } catch (Exception ex) { _logger.FailedToSend(destination, "Exception was thrown", ex); failedToSend(messages); } }
private PersistentMessage[] gatherMessagesToSend(Endpoint endpoint) { return _queueStorage.Send(actions => actions.GetMessagesToSendAndMarkThemAsInFlight(100, 1024 * 1024, endpoint)); }
public PersistentMessage[] GetMessagesToSendAndMarkThemAsInFlight(int maxNumberOfMessage, int maxSizeOfMessagesInTotal, Endpoint endpoint) { var enumerator = outgoing.GetEnumerator(); string queue = null; var messages = new List<PersistentMessage>(); while (enumerator.MoveNext()) { var msgId = outgoing.ForColumnType<GuidColumn>().Get("msg_id"); var value = (OutgoingMessageStatus) outgoing.ForColumnType<IntColumn>().Get("send_status"); var time = outgoing.ForColumnType<DateTimeColumn>().Get("time_to_send"); _logger.Debug("Scanning message {0} with status {1} to be sent at {2}", msgId, value, time); if (value != OutgoingMessageStatus.Ready) continue; // Check if the message has expired, and move it to the outgoing history. var deliverByTime = outgoing.ForColumnType<DateTimeColumn>().GetOrDefault("deliver_by"); if (deliverByTime.HasValue) { if (deliverByTime < DateTime.Now) { _logger.Info("Outgoing message {0} was not succesfully sent by its delivery time limit {1}", msgId, deliverByTime); var numOfRetries = outgoing.ForColumnType<IntColumn>().Get("number_of_retries"); MoveFailedMessageToOutgoingHistory(numOfRetries, msgId); continue; } } var maxAttempts = outgoing.ForColumnType<IntColumn>().GetOrDefault("max_attempts"); if (maxAttempts != null) { var numOfRetries = outgoing.ForColumnType<IntColumn>().Get("number_of_retries"); if (numOfRetries > maxAttempts) { _logger.Info("Outgoing message {0} has reached its max attempts of {1}", msgId, maxAttempts); MoveFailedMessageToOutgoingHistory(numOfRetries, msgId); continue; } } if (time > DateTime.Now) continue; var rowEndpoint = new Endpoint( outgoing.ForColumnType<StringColumn>().Get("address"), outgoing.ForColumnType<IntColumn>().Get("port")); if (endpoint.Equals(rowEndpoint) == false) continue; var rowQueue = outgoing.ForColumnType<StringColumn>().Get("queue"); if (queue == null) queue = rowQueue; if(queue != rowQueue) continue; var bookmark = enumerator.Current; _logger.Info("Adding message {0} to returned messages", msgId); messages.Add(new PersistentMessage { Id = new MessageId { SourceInstanceId = instanceId, MessageIdentifier = msgId }, Headers = HttpUtility.ParseQueryString(outgoing.ForColumnType<StringColumn>().Get("headers")), Queue = rowQueue, SubQueue = outgoing.ForColumnType<StringColumn>().Get("subqueue"), SentAt = outgoing.ForColumnType<DateTimeColumn>().Get("sent_at"), Data = outgoing.ForColumnType<BytesColumn>().Get("data"), Bookmark = bookmark }); outgoing.Update(() => outgoing.ForColumnType<IntColumn>().Set("send_status", (int)OutgoingMessageStatus.InFlight)); _logger.Debug("Marking output message {0} as InFlight", msgId); if (maxNumberOfMessage < messages.Count) break; if (maxSizeOfMessagesInTotal < messages.Sum(x => x.Data.Length)) break; } return messages.ToArray(); }
public void MessagesSent(IList<Message> messages, Endpoint destination) { Debug(() => "Messages {0} sent to {1}".ToFormat(string.Join(", ", messages.Select(x => x.Id)), destination)); }
public MessageId Send(ITransaction transaction, Uri uri, MessagePayload payload) { if (_waitingForAllMessagesToBeSent) throw new CannotSendWhileWaitingForAllMessagesToBeSentException("Currently waiting for all messages to be sent, so we cannot send. You probably have a race condition in your application."); var parts = uri.AbsolutePath.Substring(1).Split('/'); var queue = parts[0]; string subqueue = null; if (parts.Length > 1) { subqueue = string.Join("/", parts.Skip(1).ToArray()); } Guid msgId = Guid.Empty; var port = uri.Port; if (port == -1) port = 2200; var destination = new Endpoint(uri.Host, port); _queueStorage.Global(actions => { msgId = actions.RegisterToSend(destination, queue, subqueue, payload, transaction.Id); }); var messageId = new MessageId { SourceInstanceId = _queueStorage.Id, MessageIdentifier = msgId }; var message = new Message { Id = messageId, Data = payload.Data, Headers = payload.Headers, Queue = queue, SubQueue = subqueue }; _logger.QueuedForSend(message, destination); return messageId; }
public Guid RegisterToSend(Endpoint destination, string queue, string subQueue, MessagePayload payload, Guid transactionId) { var msgId = GuidCombGenerator.Generate(); var bookmark = outgoing.Insert(() => { outgoing.ForColumnType<GuidColumn>().Set("msg_id", msgId); outgoing.ForColumnType<GuidColumn>().Set("tx_id", transactionId); outgoing.ForColumnType<StringColumn>().Set("address", destination.Host); outgoing.ForColumnType<IntColumn>().Set("port", destination.Port); outgoing.ForColumnType<DateTimeColumn>().Set("time_to_send", DateTime.Now); outgoing.ForColumnType<DateTimeColumn>().Set("sent_at", DateTime.Now); outgoing.ForColumnType<IntColumn>().Set("send_status", (int)OutgoingMessageStatus.NotReady); outgoing.ForColumnType<StringColumn>().Set("queue", queue); outgoing.ForColumnType<StringColumn>().Set("subqueue", subQueue); outgoing.ForColumnType<StringColumn>().Set("headers", payload.Headers.ToQueryString()); outgoing.ForColumnType<BytesColumn>().Set("data", payload.Data); outgoing.ForColumnType<IntColumn>().Set("number_of_retries", 1); outgoing.ForColumnType<IntColumn>().Set("size_of_data", payload.Data.Length); if(payload.DeliverBy.HasValue) outgoing.ForColumnType<DateTimeColumn>().Set("deliver_by", payload.DeliverBy.Value); if(payload.MaxAttempts.HasValue) outgoing.ForColumnType<IntColumn>().Set("max_attempts", payload.MaxAttempts.Value); }); outgoing.MoveTo(bookmark); _logger.Debug("Created output message '{0}' for 'lq.tcp://{1}:{2}/{3}/{4}' as NotReady", msgId, destination.Host, destination.Port, queue, subQueue ); return msgId; }
public void QueuedForSend(Message message, Endpoint destination) { _queuedForSend.Add(new QueuedForSend(message, destination)); }
public void MessagesSent(IList<Message> messages, Endpoint destination) { _sent.Add(new SentMessages(destination, messages)); }
public void FailedToSend(Endpoint destination, string reason, Exception exception = null) { _sendFailures.Add(new SendFailure(destination, reason, exception)); }
public MessageQueuedForSend(Endpoint destination, Message message) { Destination = destination; Message = message; }
public MessagesSent(Message[] messages, Endpoint destination) { Messages = messages; Destination = destination; }
public void QueuedForSend(Message message, Endpoint destination) { Debug("Message {0} queued for send to {1}", message.Id, destination); }
private Sender createSender(Endpoint destination, PersistentMessage[] messages) { return new Sender(_logger) { Connected = () => _choke.SuccessfullyConnected(), Destination = destination, Messages = messages, }; }
public FailedToSend(Endpoint destination, string reason, Exception exception = null) { Destination = destination; Reason = reason; Exception = exception; }
public QueuedForSend(Message message, Endpoint destination) { Message = message; Destination = destination; }
public SendFailure(Endpoint destination, string reason, Exception exception) { Destination = destination; Reason = reason; Exception = exception; }
public SentMessages(Endpoint destination, IList<Message> messages) { Destination = destination; Messages = messages; }
public MessageEventArgs(Endpoint endpoint, Message message) { Endpoint = endpoint; Message = message; }
public void FailedToSend(Endpoint destination, string reason, Exception exception = null) { _logger.Info("Failed to send to {0}: {1}", destination, reason); _logger.DebugException("Details:", exception); }