예제 #1
0
        private async Task<bool> Invoke(MessageResult result, Action<Subscription, object> beforeInvoke, object state)
        {
            // Change the state from idle to invoking callback
            var prevState = Interlocked.CompareExchange(ref _subscriptionState,
                                                        SubscriptionState.InvokingCallback,
                                                        SubscriptionState.Idle);

            if (prevState == SubscriptionState.Disposed)
            {
                // Only allow terminal messages after dispose
                if (!result.Terminal)
                {
                    return false;
                }
            }

            beforeInvoke(this, state);

            _counters.MessageBusMessagesReceivedTotal.IncrementBy(result.TotalCount);
            _counters.MessageBusMessagesReceivedPerSec.IncrementBy(result.TotalCount);

            try
            {
                return await _callback(result, _callbackState);
            }
            finally
            {
                // Go from invoking callback to idle
                Interlocked.CompareExchange(ref _subscriptionState,
                                            SubscriptionState.Idle,
                                            SubscriptionState.InvokingCallback);
            }
        }
예제 #2
0
        private Task<bool> TriggerAcks(MessageResult result, object state)
        {
            result.Messages.Enumerate<object>(m => m.IsAck,
                                              (s, m) => ((IAckHandler)s).TriggerAck(m.CommandId),
                                              state: _ackHandler);

            return TaskAsyncHelper.True;
        }
예제 #3
0
 public virtual Task<bool> Invoke(MessageResult result)
 {
     return Invoke(result, (s, o) => { }, state: null);
 }
예제 #4
0
        public async Task Work()
        {
            // Set the state to working
            Interlocked.Exchange(ref _state, State.Working);

            var items = new List<ArraySegment<Message>>();

            while (Alive)
            {
                int totalCount;
                object state;

                items.Clear();
                PerformWork(items, out totalCount, out state);

                if (items.Count > 0)
                {
                    var messageResult = new MessageResult(items, totalCount);

                    bool result = await Invoke(messageResult, (s, o) => s.BeforeInvoke(o), state);

                    if (!result)
                    {
                        Dispose();

                        // If the callback said it's done then stop
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
        }