Ejemplo n.º 1
0
        async Task TryProcessNextMessage()
        {
            var parallelOperation = _parallelOperationsManager.TryBegin();

            if (!parallelOperation.CanContinue())
            {
                await _backoffStrategy.WaitAsync(_cancellationToken);

                return;
            }

            try
            {
                using (parallelOperation)
                    using (var context = new TransactionContextWithOwningBus(_owningBus))
                    {
                        var transportMessage = await ReceiveTransportMessage(_cancellationToken, context);

                        if (transportMessage == null)
                        {
                            context.Dispose();

                            // get out quickly if we're shutting down
                            if (_cancellationToken.IsCancellationRequested || _busDisposalCancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            // no need for another thread to rush in and discover that there is no message
                            //parallelOperation.Dispose();

                            await _backoffStrategy.WaitNoMessageAsync(_cancellationToken);

                            return;
                        }

                        _backoffStrategy.Reset();

                        try
                        {
                            AmbientTransactionContext.SetCurrent(context);
                            await ProcessMessage(context, transportMessage);
                        }
                        finally
                        {
                            AmbientTransactionContext.SetCurrent(null);
                        }
                    }
            }
            catch (OperationCanceledException) when(_cancellationToken.IsCancellationRequested || _busDisposalCancellationToken.IsCancellationRequested)
            {
                // we're shutting down
            }
            catch (Exception exception)
            {
                _log.Error(exception, "Unhandled exception in worker {workerName}", Name);
            }
        }
Ejemplo n.º 2
0
        async Task SendTransportMessage(string destinationAddress, TransportMessage transportMessage)
        {
            var transactionContext = GetCurrentTransactionContext(mustBelongToThisBus: true);

            if (transactionContext == null)
            {
                using (var context = new TransactionContextWithOwningBus(this))
                {
                    await _transport.Send(destinationAddress, transportMessage, context);

                    await context.Complete();
                }
            }
            else
            {
                await _transport.Send(destinationAddress, transportMessage, transactionContext);
            }
        }
Ejemplo n.º 3
0
        async Task InnerSend(IEnumerable <string> destinationAddresses, Message logicalMessage)
        {
            var currentTransactionContext = GetCurrentTransactionContext(mustBelongToThisBus: true);

            if (currentTransactionContext != null)
            {
                await SendUsingTransactionContext(destinationAddresses, logicalMessage, currentTransactionContext);
            }
            else
            {
                using (var context = new TransactionContextWithOwningBus(this))
                {
                    await SendUsingTransactionContext(destinationAddresses, logicalMessage, context);

                    await context.Complete();
                }
            }
        }
Ejemplo n.º 4
0
        async Task TryAsyncReceive(CancellationToken token, IDisposable parallelOperation)
        {
            try
            {
                using (parallelOperation)
                    using (var context = new TransactionContextWithOwningBus(_owningBus))
                    {
                        var transportMessage = await ReceiveTransportMessage(token, context);

                        if (transportMessage == null)
                        {
                            context.Dispose();

                            // get out quickly if we're shutting down
                            if (token.IsCancellationRequested)
                            {
                                return;
                            }

                            // no need for another thread to rush in and discover that there is no message
                            //parallelOperation.Dispose();

                            await _backoffStrategy.WaitNoMessageAsync(token);

                            return;
                        }

                        _backoffStrategy.Reset();

                        await ProcessMessage(context, transportMessage);
                    }
            }
            catch (OperationCanceledException) when(token.IsCancellationRequested || _busDisposalCancellationToken.IsCancellationRequested)
            {
                // it's fine - just a sign that we are shutting down
            }
            catch (Exception exception)
            {
                _log.Error(exception, "Unhandled exception in worker {workerName}", Name);
            }
        }
Ejemplo n.º 5
0
        protected override async Task <int> DoWork(bool isPrimaryReader, CancellationToken token)
        {
            int cnt = 0;
            TransportMessage   message = null;
            TransactionContext context;
            IDisposable        disposable = null;

            if (this.Coordinator.AsyncReadThrottling)
            {
                // better when the reads are slow like from SqlServerTransport
                disposable = await this.Coordinator.ReadThrottleAsync(isPrimaryReader);
            }
            else
            {
                // synchronous is better when the reads are fast like from the InMemoryTransport
                var waitResult = this.Coordinator.ReadThrottle(isPrimaryReader);
                // if synchronous waiting resulted in timeout (50 milliseconds by default) then wait asynchronously
                if (!waitResult.Result && !token.IsCancellationRequested)
                {
                    disposable = await this.Coordinator.ReadThrottleAsync(isPrimaryReader);
                }
                else
                {
                    disposable = waitResult;
                }
            }


            try
            {
                token.ThrowIfCancellationRequested();
                context = new TransactionContextWithOwningBus(_owningBus);
            }
            catch
            {
                disposable.Dispose();
                throw;
            }

            using (context)
            {
                try
                {
                    message = await this.ReadMessage(isPrimaryReader, this.taskId, token, context).ConfigureAwait(false);
                }
                finally
                {
                    disposable.Dispose();
                }

                cnt = message == null ? 0 : 1;

                if (cnt == 0)
                {
                    context.Dispose();
                    if (isPrimaryReader)
                    {
                        await _backoffStrategy.WaitNoMessageAsync(token);
                    }

                    return(0);
                }

                _backoffStrategy.Reset();

                this.Coordinator.OnBeforeDoWork(this);
                try
                {
                    await ProcessMessage(context, message);
                }
                finally
                {
                    this.Coordinator.OnAfterDoWork(this);
                }
            } // using Transaction Context

            return(cnt);
        }