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
                });
            }
        }
示例#2
0
        // 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);
            }
        }
示例#3
0
        // 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);
            }
        }
示例#4
0
        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
            });
        }
示例#5
0
        public void Start(ISenderCallback callback)
        {
            Connect();

            _callback = callback;

            _sending = new ActionBlock <Envelope>(send, new ExecutionDataflowBlockOptions
            {
                CancellationToken = _cancellation
            });
        }
示例#6
0
        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
                });
            }
        }
示例#8
0
        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;
                }
            }
        }
示例#9
0
        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);
        }
示例#10
0
        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);
                }
            }
        }
示例#11
0
        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,
            });
        }
示例#12
0
 public void RegisterCallback(ISenderCallback senderCallback) => _callback = senderCallback;
示例#13
0
 void ISender.Start(ISenderCallback callback)
 {
 }
示例#14
0
 public void Start(ISenderCallback callback)
 {
 }
示例#15
0
 public void Start(ISenderCallback callback)
 {
     _callback = callback;
 }
示例#16
0
        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);
        }