Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The All list contains all Consumers registered with the Queue. Consumers are added to this list when they are created and only removed when the Consumer is closed. This list is necessary to be able to iterate over all consumers in a thread-safe way without locking. The danger of using several lists instead of a single All list is that you might miss a Consumer if it moves between lists during iteration.

...

This is a list of Consumers that do not acquire messages for example Queue Browsers. These need to be handled separately because they should always be notified about new messages. Where they kept in the same list as the acquiring consumers we would have to iterate of the entire list to make sure we did not miss a non-acquiring consumer. Non-acquiring consumers can only move between the "NonAcquiring" and "NotInterested" lists.

The "NotInterested" List

This list contains all acquiring Consumers that indicated to the Queue that they currently are not interested in doing any work (i.e., taking messages). This typically happens when a Consumer/Connection is suspended due to FlowControl/TCP backpressure. The main purpose of this list is to avoid spurious wake-ups of Consumers which we know are not going to do any work.

...

This is the default list for acquiring Consumers. It signifies that they are ready to process messages. When a new message arrives on becomes available, the Queue it will notify Consumers from this list and move them to the "Notified" list. It will only notify a single interested Consumer to avoid spurious wake-ups.

...

Once an acquiring Consumer is notified that there is work to do it is moved from the "Interested" list to the "Notified" list. The QCM expects such a Consumer to either indicate that it is no longer interested (e.g., it became suspended in the meantime and therefore will not do the work we expected it to) or call AbstractQueue#deliverSingleMessage. The Consumer should remain in the "Notified" list and continue to call deliverSingleMessage until deliverSingleMessage cannot deliver a message to it any more in which case it is moved to the back of the "Interested" list. This is to decrease latency due to wake-ups when there continues to be work done available (i.e., there is a steady stream of messages). Appending it to the end of the "Interested" list ensures some level of fairness. Note that this is not perfect. It is possible that a consumer is notified but at the time it tries to pull a message of the Queue there is no longer is a message available and the Consumer is returned to the end of the "Interested" list without having done work. The assumption is that while this may happen it is unlikely to always happen to the same consumer leading to a kind of "asymptotic fairness".

...