public void Start(ISenderCallback callback) { _callback = callback; // The variance here should be in constructing the sending & buffer blocks if (_endpoint.TopicName.IsEmpty()) { _sender = _transport.TokenProvider != null ? new MessageSender(_transport.ConnectionString, _endpoint.QueueName, _transport.TokenProvider, _transport.TransportType, _transport.RetryPolicy) : new MessageSender(_transport.ConnectionString, _endpoint.QueueName, _transport.RetryPolicy); _sending = new ActionBlock <Envelope>(sendBySession, new ExecutionDataflowBlockOptions { CancellationToken = _cancellation }); } else { _sender = _transport.TokenProvider != null ? new TopicClient(_transport.ConnectionString, _endpoint.TopicName, _transport.TokenProvider, _transport.TransportType, _transport.RetryPolicy) : new TopicClient(_transport.ConnectionString, _endpoint.TopicName, _transport.RetryPolicy); _sending = new ActionBlock <Envelope>(sendBySession, new ExecutionDataflowBlockOptions { CancellationToken = _cancellation }); } }
// Nothing but actually sending here. Worry about timeouts and retries somewhere // else public static async Task Send(Stream stream, OutgoingMessageBatch batch, ISenderCallback callback) { var messageBytes = Envelope.Serialize(batch.Messages); var lengthBytes = BitConverter.GetBytes(messageBytes.Length); await stream.WriteAsync(lengthBytes, 0, lengthBytes.Length); await stream.WriteAsync(messageBytes, 0, messageBytes.Length); var bytes = await stream.ReadBytesAsync(Constants.ReceivedBuffer.Length).ConfigureAwait(false); if (bytes.SequenceEqual(Constants.ReceivedBuffer)) { callback.Successful(batch); await stream.WriteAsync(Constants.AcknowledgedBuffer, 0, Constants.AcknowledgedBuffer.Length); } else if (bytes.SequenceEqual(Constants.ProcessingFailureBuffer)) { callback.ProcessingFailure(batch); } else if (bytes.SequenceEqual(Constants.SerializationFailureBuffer)) { callback.SerializationFailure(batch); } else if (bytes.SequenceEqual(Constants.QueueDoesNotExistBuffer)) { callback.QueueDoesNotExist(batch); } }
// Nothing but actually sending here. Worry about timeouts and retries somewhere // else public static async Task Send(Stream stream, OutgoingMessageBatch batch, byte[] messageBytes, ISenderCallback callback) { messageBytes = messageBytes ?? Envelope.Serialize(batch.Messages); var lengthBytes = BitConverter.GetBytes(messageBytes.Length); await stream.WriteAsync(lengthBytes, 0, lengthBytes.Length); await stream.WriteAsync(messageBytes, 0, messageBytes.Length); // All four of the possible receive confirmation messages are the same length: 8 characters long encoded in UTF-16. var confirmationBytes = await stream.ReadBytesAsync(ReceivedBuffer.Length).ConfigureAwait(false); if (confirmationBytes.SequenceEqual(ReceivedBuffer)) { await callback.Successful(batch); await stream.WriteAsync(AcknowledgedBuffer, 0, AcknowledgedBuffer.Length); } else if (confirmationBytes.SequenceEqual(ProcessingFailureBuffer)) { await callback.ProcessingFailure(batch); } else if (confirmationBytes.SequenceEqual(SerializationFailureBuffer)) { await callback.SerializationFailure(batch); } else if (confirmationBytes.SequenceEqual(QueueDoesNotExistBuffer)) { await callback.QueueDoesNotExist(batch); } }
public void Start(ISenderCallback callback) { _callback = callback; _grouper = new ActionBlock <Envelope[]>(_ => groupMessages(_)); _outgoing = new BatchingBlock <Envelope>(200, _grouper); _sender = new ActionBlock <OutgoingMessageBatch>(sendBatch, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 5 }); }
public void Start(ISenderCallback callback) { Connect(); _callback = callback; _sending = new ActionBlock <Envelope>(send, new ExecutionDataflowBlockOptions { CancellationToken = _cancellation }); }
public async Task SendBatch(ISenderCallback callback, OutgoingMessageBatch batch) { using (var client = new TcpClient()) { await connect(client, batch.Destination) .TimeoutAfter(5000); using (var stream = client.GetStream()) { await WireProtocol.Send(stream, batch, callback).TimeoutAfter(5000); } } }
public void Start(ISenderCallback callback) { _callback = callback; _serialization = new ActionBlock <Envelope>(e => { try { e.EnsureData(); _sending.Post(e); } catch (Exception exception) { _logger.LogException(exception, e.Id, "Serialization Failure!"); } }); // The variance here should be in constructing the sending & buffer blocks if (_endpoint.Uri.TopicName.IsEmpty()) { _sender = _endpoint.TokenProvider != null ? new MessageSender(_endpoint.ConnectionString, _endpoint.Uri.QueueName, _endpoint.TokenProvider, _endpoint.TransportType, _endpoint.RetryPolicy) : new MessageSender(_endpoint.ConnectionString, _endpoint.Uri.QueueName, _endpoint.RetryPolicy); _sending = new ActionBlock <Envelope>(sendBySession, new ExecutionDataflowBlockOptions { CancellationToken = _cancellation }); } else if (_endpoint.Uri.IsMessageSpecificTopic()) { _sending = new ActionBlock <Envelope>(sendByMessageTopicAndSession, new ExecutionDataflowBlockOptions { CancellationToken = _cancellation }); } else { _sender = _endpoint.TokenProvider != null ? new TopicClient(_endpoint.ConnectionString, _endpoint.Uri.TopicName, _endpoint.TokenProvider, _endpoint.TransportType, _endpoint.RetryPolicy) : new TopicClient(_endpoint.ConnectionString, _endpoint.Uri.TopicName, _endpoint.RetryPolicy); _sending = new ActionBlock <Envelope>(sendBySession, new ExecutionDataflowBlockOptions { CancellationToken = _cancellation }); } }
public async Task SendBatch(ISenderCallback callback, OutgoingMessageBatch batch) { var bytes = batch.Data; var request = new HttpRequestMessage { Method = HttpMethod.Put, RequestUri = batch.Destination, }; //request.Headers.Add("content-length", bytes.Length.ToString()); request.Headers.Add(TransportEndpoint.EnvelopeSenderHeader, _settings.ServiceName); request.Content = new ByteArrayContent(bytes); // TODO -- security here? try { var response = await _client.SendAsync(request); if (response.StatusCode == HttpStatusCode.ServiceUnavailable) { throw new Exception("The server returned 503, service too busy"); } else if (response.StatusCode != HttpStatusCode.OK) { throw new Exception($"Unable to send message batch to " + batch.Destination); } } catch (TaskCanceledException e) { if (!e.CancellationToken.IsCancellationRequested) { await callback.TimedOut(batch); } else { throw; } } }
public void Start(ISenderCallback callback) { _callback = callback; _sender = new ActionBlock <OutgoingMessageBatch>(SendBatch, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1, CancellationToken = _cancellation }); _serializing = new ActionBlock <Envelope>(e => { try { e.EnsureData(); _batching.Post(e); } catch (Exception ex) { _logger.LogException(ex, message: $"Error while trying to serialize envelope {e}"); } }, new ExecutionDataflowBlockOptions { CancellationToken = _cancellation }); _batchWriting = new TransformBlock <Envelope[], OutgoingMessageBatch>( envelopes => { var batch = new OutgoingMessageBatch(Destination, envelopes); _queued += batch.Messages.Count; return(batch); }); _batchWriting.LinkTo(_sender); _batching = new BatchingBlock <Envelope>(200, _batchWriting, _cancellation); }
public async Task SendBatch(ISenderCallback callback, OutgoingMessageBatch batch) { if (batch.Data.Length == 0) { throw new Exception("No data to be sent"); } using (var client = new TcpClient()) { var connection = connect(client, batch.Destination) .TimeoutAfter(5000); await connection; if (connection.IsCompleted) { using (var stream = client.GetStream()) { var protocolTimeout = WireProtocol.Send(stream, batch, batch.Data, callback); //var protocolTimeout = .TimeoutAfter(5000); await protocolTimeout.ConfigureAwait(false); if (!protocolTimeout.IsCompleted) { await callback.TimedOut(batch); } if (protocolTimeout.IsFaulted) { await callback.ProcessingFailure(batch, protocolTimeout.Exception); } } } else { await callback.TimedOut(batch); } } }
public void Start(ISenderCallback callback) { _callback = callback; _serialization = new ActionBlock <Envelope>(e => { try { e.EnsureData(); _sending.Post(e); } catch (Exception exception) { _logger.LogException(exception, e.Id, "Serialization Failure!"); } }); _sending = new ActionBlock <Envelope>(send, new ExecutionDataflowBlockOptions { CancellationToken = _cancellation, }); }
public void RegisterCallback(ISenderCallback senderCallback) => _callback = senderCallback;
void ISender.Start(ISenderCallback callback) { }
public void Start(ISenderCallback callback) { }
public void Start(ISenderCallback callback) { _callback = callback; }
public void Start(ISenderCallback callback) { _callback = callback; _sender = new ActionBlock <OutgoingMessageBatch>(SendBatch, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1, CancellationToken = _cancellation, BoundedCapacity = DataflowBlockOptions.Unbounded }); _sender.Completion.ContinueWith(x => { if (x.IsFaulted) { // TODO -- need to restart things!!! _logger.LogException(x.Exception); } }, _cancellation); _serializing = new ActionBlock <Envelope>(async e => { try { e.EnsureData(); await _batching.SendAsync(e); } catch (Exception ex) { _logger.LogException(ex, message: $"Error while trying to serialize envelope {e}"); } }, new ExecutionDataflowBlockOptions { CancellationToken = _cancellation, BoundedCapacity = DataflowBlockOptions.Unbounded }); _serializing.Completion.ContinueWith(x => { if (x.IsFaulted) { // TODO -- need to restart things!!! _logger.LogException(x.Exception); } }, _cancellation); _batchWriting = new TransformBlock <Envelope[], OutgoingMessageBatch>( envelopes => { var batch = new OutgoingMessageBatch(Destination, envelopes); _queued += batch.Messages.Count; return(batch); }, new ExecutionDataflowBlockOptions { BoundedCapacity = DataflowBlockOptions.Unbounded, MaxDegreeOfParallelism = 10 }); _batchWriting.Completion.ContinueWith(x => { if (x.IsFaulted) { // TODO -- need to restart things!!! _logger.LogException(x.Exception); } }, _cancellation); _batchWriting.LinkTo(_sender); _batching = new BatchingBlock <Envelope>(200, _batchWriting, _cancellation); _batching.Completion.ContinueWith(x => { if (x.IsFaulted) { // TODO -- need to restart things!!! _logger.LogException(x.Exception); } }, _cancellation); }