public void TryDelivery(QueueEntry head) { // TODO: check link credit to determine if we can deliver if (!HasCreditToDeliver()) { return; } lock (syncRoot) { var next = head.GetNextValidEntry(); while (next != null) { if (next.IsAvailable) { // TODO: FILTER out entries we don't care about if (queue.TryAcquire(next, this)) { break; // if not acquired, we'll try again with the next one } } // loop until we get an available entry to deliver // or null next = next.GetNextValidEntry(); } if (next == null) { return; // nothing to deliver } if (next != null) { // message acquired and ready to be delivered OnMessageAquired(next); } } }
public void WriteArchived(ConcurrentQueue queue, QueueEntry entry) { buffer.Enqueue( string.Format("Queue {0} Archived {1} DateTime {2} TTL {3} DeliveryCount {4}", queue.QueueID, entry.SeqNum, entry.EnqueueDateTime, entry.TTL, entry.DeliveryCount)); flushSignal.Set(); }
/// <summary> /// Wraps up call to Interlocked.CompareExchange to compare & swap a new /// "next" QueueEntry pointer. /// /// Returns true if the compare & swap succeeded, false other. /// </summary> public bool CompareAndSwapNext(QueueEntry n_next, QueueEntry p_next) { return(Interlocked.CompareExchange(ref next, n_next, p_next) == p_next); }
/// <summary> /// Compares the sequence number of this QueueEntry to another QueueEntry for ordering purposes. /// </summary> public int CompareTo(QueueEntry item) { // TODO: sequence number wrapping return(SeqNum > item.SeqNum ? 1 : SeqNum < item.SeqNum ? -1 : 0); }
protected abstract void OnMessageAquired(QueueEntry next);
public bool TryAcquire(QueueEntry entry, Consumer consumer) { return(entry.TryAcquire(consumer)); }
public void Archive(QueueEntry entry) { entry.Archive(); logWriter.WriteArchived(this, entry); queueList.OnEntryArchived(entry); }
public void Release(QueueEntry entry, bool incrementDeliveryCount) { entry.Release(incrementDeliveryCount); messageDeliveryPumpSignal.Set(); // new message available, signal to pump to consumers }