protected override void OnProcessTransfer(Delivery delivery, Transfer transfer, Frame rawFrame) { throw new NotImplementedException(); }
protected override void OnDisposeDeliveryInternal(Delivery delivery) { throw new NotImplementedException(); }
void OnTxnDischarge(Delivery delivery, bool fail) { if (!fail) { BrokerMessage message = (BrokerMessage)delivery; if (message.Node != null && message.Node.List != null) { this.queue.Dequeue(message); } this.link.DisposeDelivery(delivery, true, delivery.State); delivery.Dispose(); } }
protected void AddDelivery(Delivery delivery) { // Caller should hold the lock delivery.DeliveryId = this.nextDeliveryId; this.nextDeliveryId.Increment(); if (!delivery.Settled) { Delivery.Add(ref this.firstUnsettled, ref this.lastUnsettled, delivery); } }
void OnTxnDischarge(Delivery delivery, bool fail) { if (!fail) { this.queue.Enqueue(new BrokerMessage((AmqpMessage)delivery)); } }
// delivery public static bool Transactional(this Delivery delivery) { return(delivery.State != null && delivery.State.DescriptorCode == TransactionalState.Code); }
public bool OnAcceptTransfer(Delivery delivery, Transfer transfer, bool newDelivery) { try { this.incomingChannel.OnAcceptTransfer(delivery, transfer, newDelivery); return true; } catch (AmqpException exception) { this.SafeClose(exception); return false; } }
public void DisposeDelivery(Delivery delivery, bool settled, DeliveryState state, bool noFlush) { if (delivery.Settled) { this.OnWindowMoved(1); return; } bool scheduleTimer = false; Delivery toDispose = null; lock (this.syncRoot) { delivery.StateChanged = true; delivery.Settled = settled; delivery.State = state; if (!delivery.Batchable) { delivery.StateChanged = false; toDispose = delivery; if (delivery.Settled) { Delivery.Remove(ref this.firstUnsettled, ref this.lastUnsettled, delivery); } } else if (this.sendingDisposition || noFlush) { return; } else if (this.session.settings.DispositionInterval == TimeSpan.Zero || ++this.needDispositionCount >= this.session.settings.DispositionThreshold) { this.sendingDisposition = true; this.needDispositionCount = 0; } else if (!this.timerScheduled) { this.timerScheduled = true; scheduleTimer = true; } } if (toDispose != null) { this.SendDisposition(new DispositionInfo() { First = toDispose }); if (delivery.Settled) { this.OnWindowMoved(1); } } else if (scheduleTimer) { if (this.dispositionTimer == null) { this.dispositionTimer = new Timer( s => DispositionTimerCallback(s), this, this.session.settings.DispositionInterval, Timeout.InfiniteTimeSpan); } else { this.dispositionTimer.Change(this.session.settings.DispositionInterval, Timeout.InfiniteTimeSpan); } } else { this.SendDisposition(); } }
void SendDisposition() { List <DispositionInfo> disposedDeliveries = new List <DispositionInfo>(); int settledCount = 0; lock (this.syncRoot) { Delivery current = this.firstUnsettled; Delivery firstChanged = null; uint? lastId = null; while (current != null) { if (current.StateChanged) { if (firstChanged == null) { firstChanged = current; } else { if (current.Settled == firstChanged.Settled && CanBatch(current.State as Outcome, firstChanged.State as Outcome)) { lastId = current.DeliveryId.Value; } else { disposedDeliveries.Add(new DispositionInfo() { First = firstChanged, Last = lastId }); firstChanged = current; lastId = null; } } // Move next and remove if settled if (current.Settled) { Delivery temp = current; current = current.Next; ++settledCount; Delivery.Remove(ref this.firstUnsettled, ref this.lastUnsettled, temp); } else { current.StateChanged = false; current = current.Next; } } else { if (firstChanged != null) { disposedDeliveries.Add(new DispositionInfo() { First = firstChanged, Last = lastId }); firstChanged = null; lastId = null; } current = current.Next; } } if (firstChanged != null) { disposedDeliveries.Add(new DispositionInfo() { First = firstChanged, Last = lastId }); } this.sendingDisposition = false; } if (disposedDeliveries.Count > 0) { foreach (var info in disposedDeliveries) { this.SendDisposition(info); } } if (settledCount > 0) { this.OnWindowMoved(settledCount); } }
public void OnReceiveDisposition(Disposition disposition) { SequenceNumber first = disposition.First.Value; SequenceNumber last = disposition.Last ?? first; if (last < first) { // Should be a protocol error return; } List <Delivery> disposedDeliveries = new List <Delivery>(); int settledCount = 0; lock (this.syncRoot) { if (first >= this.nextDeliveryId) { return; } if (last > this.nextDeliveryId) { last = this.nextDeliveryId; } bool settled = disposition.Settled(); Delivery current = this.firstUnsettled; while (current != null) { SequenceNumber sn = current.DeliveryId.Value; if (sn < first) { current = current.Next; } else if (sn > last) { break; } else { Delivery delivery = current; current = current.Next; delivery.Settled = settled; delivery.State = disposition.State; if (settled) { ++settledCount; Delivery.Remove(ref this.firstUnsettled, ref this.lastUnsettled, delivery); } disposedDeliveries.Add(delivery); } } } if (disposedDeliveries.Count > 0) { foreach (Delivery delivery in disposedDeliveries) { delivery.Link.OnDisposeDelivery(delivery); } if (settledCount > 0) { this.OnWindowMoved(settledCount); } } }
/// <summary> /// Attempts to send the transfer over the outgoing channel. /// </summary> /// <param name="delivery">The delivery owning the transfer.</param> /// <param name="transfer">The transfer command to send.</param> /// <param name="payload">The payload to carry in the transfer frame.</param> /// <returns>True if the transfer is sent; false if session window is 0.</returns> public bool TrySendTransfer(Delivery delivery, Transfer transfer, ByteBuffer payload) { // delivery MUST be null for continued transfer fragments return(this.outgoingChannel.TrySendTransfer(delivery, transfer, payload)); }
// delivery MUST be null for continued transfer fragments public bool TrySendTransfer(Delivery delivery, Transfer transfer, ArraySegment<byte>[] payload) { return this.outgoingChannel.TrySendTransfer(delivery, transfer, payload); }
public static bool IsReceivedDeliveryState(this Delivery delivery) { return(delivery.State != null && delivery.State.DescriptorCode == Received.Code); }
public void DisposeDelivery(AmqpLink link, Delivery delivery, bool settled, DeliveryState state, bool noFlush) { if (link.IsReceiver) { this.incomingChannel.DisposeDelivery(delivery, settled, state, noFlush); } else { this.outgoingChannel.DisposeDelivery(delivery, settled, state, noFlush); } }
public static void Remove(ref Delivery first, ref Delivery last, Delivery delivery) { if (delivery == first) { first = delivery.Next; if (first == null) { last = null; } else { first.Previous = null; } } else if (delivery == last) { last = delivery.Previous; last.Next = null; } else if (delivery.Previous != null && delivery.Next != null) { delivery.Previous.Next = delivery.Next; delivery.Next.Previous = delivery.Previous; } delivery.Previous = null; delivery.Next = null; }
public void DisposeDelivery(Delivery delivery, bool settled, DeliveryState state, bool noFlush) { if (delivery.Settled) { this.OnWindowMoved(1); return; } bool scheduleTimer = false; Delivery toDispose = null; lock (this.syncRoot) { delivery.StateChanged = true; delivery.Settled = settled; delivery.State = state; if (!delivery.Batchable) { delivery.StateChanged = false; toDispose = delivery; if (delivery.Settled) { Delivery.Remove(ref this.firstUnsettled, ref this.lastUnsettled, delivery); } } else if (this.sendingDisposition || noFlush) { return; } else if (this.session.settings.DispositionInterval == TimeSpan.Zero || ++this.needDispositionCount >= this.session.settings.DispositionThreshold) { this.sendingDisposition = true; this.needDispositionCount = 0; } else if (!this.timerScheduled) { this.timerScheduled = true; scheduleTimer = true; } } if (toDispose != null) { this.SendDisposition(new DispositionInfo() { First = toDispose }); if (delivery.Settled) { this.OnWindowMoved(1); } } else if (scheduleTimer) { Fx.Assert(this.dispositionTimer != null, "Disposition timer cannot be null"); this.dispositionTimer.Change(this.session.settings.DispositionInterval, Timeout.InfiniteTimeSpan); } else { this.SendDisposition(); } }
public static void Add(ref Delivery first, ref Delivery last, Delivery delivery) { Fx.Assert(delivery.Previous == null && delivery.Next == null, "delivery is already in a list"); if (first == null) { Fx.Assert(last == null, "last must be null when first is null"); first = last = delivery; } else { last.Next = delivery; delivery.Previous = last; last = delivery; } }
public bool TrySendTransfer(Delivery delivery, Transfer transfer, ArraySegment<byte>[] payload) { lock (this.SyncRoot) { if (this.outgoingWindow == 0) { AmqpTrace.Provider.AmqpSessionWindowClosed(this, (int)this.nextOutgoingId.Value); return false; } this.nextOutgoingId.Increment(); if (this.outgoingWindow < uint.MaxValue) { this.outgoingWindow--; } if (delivery != null) { this.AddDelivery(delivery); transfer.DeliveryId = delivery.DeliveryId.Value; } this.Session.SendCommand(transfer, payload); } return true; }
public void OnAcceptTransfer(Delivery delivery, Transfer transfer, bool newDelivery) { if (!this.transferEverReceived) { this.OnReceiveFirstTransfer(transfer); this.transferEverReceived = true; } bool canAccept = false; lock (this.SyncRoot) { if (this.incomingWindow > 0) { canAccept = true; if (newDelivery) { this.AddDelivery(delivery); } this.nextIncomingId.Increment(); if (this.incomingWindow < uint.MaxValue) { this.incomingWindow--; } } } if (!canAccept) { AmqpTrace.Provider.AmqpSessionWindowClosed(this, (int)this.nextIncomingId.Value); throw new AmqpException(AmqpErrorCode.WindowViolation, null); } if (!newDelivery) { // continued transfer for existing delivery: move window forward this.OnWindowMoved(1); } }
void OnDispose(Delivery delivery) { if (delivery.Transactional()) { Transaction txn = this.queue.broker.txnManager.GetTransaction(((TransactionalState)delivery.State).TxnId); txn.AddOperation(delivery, this.OnTxnDischarge); this.link.DisposeDelivery(delivery, false, delivery.State, false); } else { if (!delivery.Settled) { this.link.DisposeDelivery(delivery, true, delivery.State); } BrokerMessage message = (BrokerMessage)delivery; if (delivery.State.DescriptorCode == Accepted.Code || delivery.State.DescriptorCode == Rejected.Code || delivery.State.DescriptorCode == Modified.Code) { if (message.Node != null && message.Node.List != null) { this.queue.Dequeue(message); } delivery.Dispose(); } else if (delivery.State.DescriptorCode == Released.Code) { this.queue.Unlock(message); } } }
public override bool CreateDelivery(Transfer transfer, out Delivery delivery) { throw new NotImplementedException(); }
public void AddOperation(Delivery delivery, Action<Delivery, bool> commit) { lock (this.operations) { this.operations.Enqueue(Tuple.Create(delivery, commit)); } }
protected override bool CreateDelivery(Transfer transfer, out Delivery delivery) { throw new NotImplementedException(); }