Esempio n. 1
0
        async void TryReceiveNewMessage()
        {
            using (var operation = _parallelOperationsManager.TryBegin())
            {
                // if we didn't get to do our thing, let the OS decide what to do next.... we don't hog the processor
                if (!operation.CanContinue())
                {
                    Thread.Yield();
                    return;
                }

                using (var transactionContext = new DefaultTransactionContext())
                {
                    transactionContext.Items["CancellationToken"] = _cancellationTokenSource.Token;
                    AmbientTransactionContext.Current = transactionContext;
                    try
                    {
                        var result = await TryReceiveTransportMessage(transactionContext, _cancellationTokenSource.Token);

                        if (result.Exception != null)
                        {
                            if (result.Exception is TaskCanceledException || result.Exception is OperationCanceledException)
                            {
                                // this is normal - we're being shut down so we just return quickly
                                transactionContext.Dispose();
                                return;
                            }

                            _log.Warn("An error occurred when attempting to receive transport message: {0}", result.Exception);

                            // error: finish the tx and wait....
                            transactionContext.Dispose();

                            await _backoffStrategy.WaitError();
                            return;
                        }

                        var message = result.TransportMessage;
                        if (message == null)
                        {
                            // no message: finish the tx and wait....
                            await transactionContext.Complete();
                            transactionContext.Dispose();

                            await _backoffStrategy.Wait();
                            return;
                        }

                        // we got a message, so we reset the backoff strategy
                        _backoffStrategy.Reset();

                        var context = new IncomingStepContext(message, transactionContext);
                        var stagedReceiveSteps = _pipeline.ReceivePipeline();

                        await _pipelineInvoker.Invoke(context, stagedReceiveSteps);

                        try
                        {
                            await transactionContext.Complete();
                        }
                        catch (Exception exception)
                        {
                            _log.Error(exception, "An error occurred when attempting to complete the transaction context");
                        }
                    }
                    catch (Exception exception)
                    {
                        // we should not end up here unless something is off....
                        _log.Error(exception, "Unhandled exception in thread worker - the pipeline didn't handle its own errors (this is bad)");
                        Thread.Sleep(100);
                    }
                    finally
                    {
                        AmbientTransactionContext.Current = null;
                    }
                }
            }
        }
Esempio n. 2
0
        async void TryAsyncReceive(CancellationToken token, IDisposable parallelOperation)
        {
            try
            {
                using (parallelOperation)
                using (var context = new DefaultTransactionContext())
                {
                    var transportMessage = await ReceiveTransportMessage(token, context);

                    if (transportMessage == null)
                    {
                        context.Dispose();
                        
                        // no need for another thread to rush in and discover that there is no message
                        //parallelOperation.Dispose();

                        _backoffStrategy.WaitNoMessage();
                        return;
                    }

                    _backoffStrategy.Reset();

                    await ProcessMessage(context, transportMessage);
                }
            }
            catch (TaskCanceledException)
            {
                // it's fine - just a sign that we are shutting down
            }
            catch (OperationCanceledException)
            {
                // it's fine - just a sign that we are shutting down
            }
            catch (Exception exception)
            {
                _log.Error(exception, "Unhandled exception in thread pool worker");
            }
        }