Example #1
0
        async Task Consume()
        {
            var prefetchCount = Math.Max(1000, _consumerContext.ReceiveSettings.CheckpointMessageCount / 10);
            var executor      = new ChannelExecutor(prefetchCount, _consumerContext.ReceiveSettings.ConcurrencyLimit);

            await _consumerContext.Subscribe().ConfigureAwait(false);

            SetReady();

            try
            {
                while (!_cancellationTokenSource.IsCancellationRequested)
                {
                    ConsumeResult <TKey, TValue> consumeResult = await _consumerContext.Consume(_cancellationTokenSource.Token).ConfigureAwait(false);

                    await executor.Push(() => Handle(consumeResult), Stopping).ConfigureAwait(false);
                }
            }
            catch (OperationCanceledException exception) when(exception.CancellationToken == Stopping ||
                                                              exception.CancellationToken == _cancellationTokenSource.Token)
            {
            }
            catch (Exception exception)
            {
                LogContext.Error?.Log(exception, "Consume Loop faulted");
            }
            finally
            {
                await executor.DisposeAsync().ConfigureAwait(false);
            }

            SetCompleted(TaskUtil.Completed);
        }
Example #2
0
        async Task <int> ReceiveMessages(int messageLimit, ChannelExecutor executor)
        {
            IList <Message> messages = await _client.ReceiveMessages(_receiveSettings.EntityName, messageLimit, _receiveSettings.WaitTimeSeconds, Stopping)
                                       .ConfigureAwait(false);

            await Task.WhenAll(messages.Select(message => executor.Push(() => HandleMessage(message), Stopping))).ConfigureAwait(false);

            return(messages.Count);
        }
Example #3
0
        public async Task Connect(CancellationToken cancellationToken)
        {
            var logContext   = _context.LogContext;
            var inputAddress = _context.InputAddress;

            LogContext.SetCurrentIfNull(logContext);

            _cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

            async Task ProcessEventAsync(ProcessEventArgs arg)
            {
                LogContext.SetCurrentIfNull(logContext);

                try
                {
                    await _executor.Push(() => _transport.Handle(arg, cancellationToken), _cancellationTokenSource.Token).ConfigureAwait(false);
                }
                catch (OperationCanceledException e) when(e.CancellationToken == _cancellationTokenSource.Token)
                {
                }
            }

            async Task ProcessErrorAsync(ProcessErrorEventArgs arg)
            {
                var faultedEvent = new ReceiveTransportFaultedEvent(inputAddress, arg.Exception);

                await _context.TransportObservers.Faulted(faultedEvent).ConfigureAwait(false);

                await _context.EndpointObservers.Faulted(new ReceiveEndpointFaultedEvent(faultedEvent, this)).ConfigureAwait(false);
            }

            _processor.ProcessEventAsync += ProcessEventAsync;
            _processor.ProcessErrorAsync += ProcessErrorAsync;

            try
            {
                await _blobContainerClient.CreateIfNotExistsAsync(cancellationToken : cancellationToken).ConfigureAwait(false);
            }
            catch (RequestFailedException exception)
            {
                LogContext.Warning?.Log(exception, "Azure Blob Container does not exist: {Address}", _blobContainerClient.Uri);
            }

            LogContext.Debug?.Log("EventHub processor starting: {EventHubName}", _processor.EventHubName);

            await _processor.StartProcessingAsync(cancellationToken).ConfigureAwait(false);

            await _context.TransportObservers.Ready(new ReceiveTransportReadyEvent(inputAddress)).ConfigureAwait(false);

            var endpointReadyEvent = new ReceiveEndpointReadyEvent(_context.InputAddress, this, true);

            _started.TrySetResult(endpointReadyEvent);

            await _context.EndpointObservers.Ready(endpointReadyEvent).ConfigureAwait(false);
        }
Example #4
0
        async Task HandleMessage(ProcessEventArgs eventArgs)
        {
            LogContext.SetCurrentIfNull(_context.LogContext);

            try
            {
                await _executor.Push(() => Handle(eventArgs), Stopping).ConfigureAwait(false);
            }
            catch (OperationCanceledException e) when(e.CancellationToken == Stopping)
            {
            }
        }
        public Task Start(CancellationToken cancellationToken)
        {
            var logContext = _context.LogContext;

            LogContext.SetCurrentIfNull(logContext);

            _cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

            // TODO this feels like it needs to be more resilient, right now one error and it exits

            _consumerTask = Task.Run(async() =>
            {
                var inputAddress = _context.InputAddress;
                await _context.TransportObservers.Ready(new ReceiveTransportReadyEvent(inputAddress)).ConfigureAwait(false);

                var endpointReadyEvent = new ReceiveEndpointReadyEvent(_context.InputAddress, this, true);
                _started.TrySetResult(endpointReadyEvent);

                await _context.EndpointObservers.Ready(endpointReadyEvent).ConfigureAwait(false);

                LogContext.Debug?.Log("Kafka consumer started: {InputAddress}", _context.InputAddress);

                while (!_cancellationTokenSource.IsCancellationRequested)
                {
                    LogContext.SetCurrentIfNull(logContext);
                    try
                    {
                        ConsumeResult <TKey, TValue> message = _consumer.Consume(_cancellationTokenSource.Token);

                        await _executor.Push(() => _transport.Handle(message, cancellationToken), _cancellationTokenSource.Token).ConfigureAwait(false);
                    }
                    catch (OperationCanceledException e) when(e.CancellationToken == _cancellationTokenSource.Token)
                    {
                    }
                    catch (Exception exception)
                    {
                        var faultedEvent = new ReceiveTransportFaultedEvent(inputAddress, exception);

                        await _context.TransportObservers.Faulted(faultedEvent).ConfigureAwait(false);
                        await _context.EndpointObservers.Faulted(new ReceiveEndpointFaultedEvent(faultedEvent, this)).ConfigureAwait(false);

                        throw;
                    }
                }
            }, cancellationToken);

            _consumer.Subscribe(_topic);

            return(_consumerTask.IsCompleted ? _consumerTask : TaskUtil.Completed);
        }
Example #6
0
        async Task <int> ReceiveAndHandleMessages(int messageLimit, ChannelExecutor executor)
        {
            try
            {
                IList <Message> messages = await _client.ReceiveMessages(_receiveSettings.EntityName, messageLimit, _receiveSettings.WaitTimeSeconds, Stopping)
                                           .ConfigureAwait(false);

                foreach (var message in messages)
                {
                    await executor.Push(() => HandleMessage(message), Stopping).ConfigureAwait(false);
                }

                return(messages.Count);
            }
            catch (OperationCanceledException)
            {
                return(0);
            }
        }
Example #7
0
            public override void Post(SendOrPostCallback callback, object state)
            {
                if (callback == null)
                {
                    throw new ArgumentNullException(nameof(callback));
                }

                if (_completed)
                {
                    throw new TaskSchedulerException("The synchronization context was already completed");
                }

                try
                {
                    _executor?.Push(async() => callback(state), _cancellationToken);
                }
                catch (InvalidOperationException)
                {
                }
            }
Example #8
0
        public async Task Should_be_performant()
        {
            long value = 0;

            var executor = new ChannelExecutor(10);

            const int limit = 10000;

            for (var i = 0; i < limit; i++)
            {
                await executor.Push(() =>
                {
                    Interlocked.Increment(ref value);

                    return(Task.CompletedTask);
                });
            }

            await executor.DisposeAsync().ConfigureAwait(false);

            Assert.That(value, Is.EqualTo(10000));
        }
 public Task Deliver(DeliveryContext <InMemoryTransportMessage> context)
 {
     return(context.WasAlreadyDelivered(this)
         ? Task.FromResult(false)
         : _executor.Push(() => DispatchMessage(context.Package)));
 }