Example #1
0
        void CancelPendingOperations(bool aborted, out Queue <AmqpMessage> messagesToRelease)
        {
            messagesToRelease = null;
            LinkedList <ReceiveAsyncResult> waiters = null;

            lock (this.SyncRoot)
            {
                messagesToRelease = this.messageQueue;
                waiters           = this.waiterList;
                this.messageQueue = null;
                this.waiterList   = null;
            }

            if (waiters != null)
            {
                ActionItem.Schedule(o =>
                {
                    var state = (Tuple <LinkedList <ReceiveAsyncResult>, bool>)o;
                    LinkedList <ReceiveAsyncResult> waitersToCancel = state.Item1;
                    foreach (ReceiveAsyncResult waiter in waitersToCancel)
                    {
                        if (state.Item2)
                        {
                            waiter.Cancel();
                        }
                        else
                        {
                            waiter.Signal(null, false, null);
                        }
                    }
                },
                                    new Tuple <LinkedList <ReceiveAsyncResult>, bool>(waiters, aborted));
            }

            if (this.pendingDispositions != null)
            {
                this.pendingDispositions.Abort();
            }
        }
Example #2
0
        bool IWorkDelegate <AmqpMessage> .Invoke(AmqpMessage message)
        {
            DeliveryState deliveryState = message.State;

            if (deliveryState != null && deliveryState.DescriptorCode == Released.Code)
            {
                // message has been cancelled (e.g. timed out)
                return(true);
            }

            bool success = this.TrySendDelivery(message);

            if (!success &&
                this.Session.State == AmqpObjectState.Opened &&
                DateTime.UtcNow - this.lastFlowRequestTime >= MinRequestCreditWindow)
            {
                // Tell the other side that we have some messages to send
                this.lastFlowRequestTime = DateTime.UtcNow;
                ActionItem.Schedule(s => OnRequestCredit(s), this);
            }

            return(success);
        }
Example #3
0
        void OnReceiveMessage(AmqpMessage message)
        {
            if (this.messageListener != null)
            {
                this.messageListener(message);
            }
            else
            {
                ReceiveAsyncResult waiter = null;
                int  creditToIssue        = 0;
                bool releaseMessage       = false;
                lock (this.SyncRoot)
                {
                    if (this.waiterList != null && this.waiterList.Count > 0)
                    {
                        var firstWaiter = this.waiterList.First.Value;

                        if (this.messageQueue.IsPrefetchingBySize)
                        {
                            if (this.messageQueue.UpdateCreditToIssue(message))
                            {
                                this.SetTotalLinkCredit(this.messageQueue.BoundedTotalLinkCredit, true);
                            }
                        }

                        firstWaiter.Add(message);
                        if (firstWaiter.RequestedMessageCount == 1 || firstWaiter.MessageCount >= firstWaiter.RequestedMessageCount)
                        {
                            this.waiterList.RemoveFirst();
                            firstWaiter.OnRemoved();
                            creditToIssue = this.Settings.AutoSendFlow ? 0 : this.GetOnDemandReceiveCredit();
                            waiter        = firstWaiter;
                        }
                    }
                    else if (!this.Settings.AutoSendFlow && this.Settings.SettleType != SettleMode.SettleOnSend)
                    {
                        releaseMessage = true;
                    }
                    else if (this.messageQueue != null)
                    {
                        this.messageQueue.Enqueue(message);
                        AmqpTrace.Provider.AmqpCacheMessage(
                            this,
                            message.DeliveryId.Value,
                            this.messageQueue.Count,
                            this.messageQueue.IsPrefetchingBySize,
                            this.TotalCacheSizeInBytes ?? 0,
                            this.Settings == null ? 0 : this.Settings.TotalLinkCredit,
                            this.LinkCredit);
                    }
                }

                if (releaseMessage)
                {
                    this.ReleaseMessage(message);
                    message.Dispose();
                }

                if (creditToIssue > 0)
                {
                    this.IssueCredit((uint)creditToIssue, false, AmqpConstants.NullBinary);
                }

                if (waiter != null)
                {
                    // Schedule the completion on another thread so we don't block the I/O thread
                    ActionItem.Schedule(o => { var w = (ReceiveAsyncResult)o; w.Signal(false); }, waiter);
                }
            }
        }