qpid-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (Jira)" <j...@apache.org>
Subject [jira] [Commented] (QPID-8361) [Broker-J] Create a developer guide for Qpid Broker-J
Date Tue, 17 Sep 2019 13:32:00 GMT

    [ https://issues.apache.org/jira/browse/QPID-8361?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16931463#comment-16931463
] 

ASF GitHub Bot commented on QPID-8361:
--------------------------------------

alex-rufous commented on pull request #36: QPID-8361: [Broker-J] Create a developer guide
for Qpid Broker-J
URL: https://github.com/apache/qpid-broker-j/pull/36#discussion_r325167594
 
 

 ##########
 File path: doc/developer-guide/src/main/markdown/consumer-queue-interactions.md
 ##########
 @@ -0,0 +1,144 @@
+# Consumer-Queue Interactions
+
+This article overviews implementation behind interactions between consumers and queue.
+
+The main players are
+
+ * Queue - model object providing the messaging queue functionality.
+    * QueueConsumerManager - queue entity responsible for managing queue consumers
+ * Consumers - queue consumers
+
+The `ConsumerTarget` is the broker-side representation of a consuming client. Due to multi-queue
consumers
+a `ConsumerTarget` has one or more `Consumers` associated with one `Queue` each. It is this
`Consumer` that
+interacts with the `Queue`.
+
+## Responsibilities
+
+A `Queue` is responsible for notification of at least one interested `Consumer` when there
is work to be done
+(message to consume).
+
+A `Consumer` is responsible for notification of its `Queue` when it is ready to do some work
(for example, consume messages).
+When notified by a `Queue` of available work, a `Consumer` MUST try to pull messages of said
`Queue` until either
+it notifies the `Queue` that it is no longer interested OR there are no more messages available
on the `Queue`
+(i.e., the Queue does not return a message).
+
+### Simple Example
+
+ 1. `Message` arrives on the `Queue`
+ 2. The `Queue` notifies some interested `Consumers` that there is work to be done
+ 3. The `Consumers` notify their `ConsumerTarget` that they would like to do work
+ 4. The `ConsumerTargets` notify their `Sessions` that they would like to do work
+ 5. The `Sessions` notify their `Connections` that they would like to do work
+ 6. The `Connections` schedule themselves. This is the switch from the incoming `Thread`
to the `IO-Thread`.
+ 7. The `Scheduler` kicks off a IO-Thread to process the work of a `Connection`
+ 8. The `Connection` iterates over its `Sessions` that want to do work
+ 9. The `Sessions` iterate over its `ConsumerTargets` that want to do work
+ 10. The `ConsumerTargets` iterate over its `Consumers` that want to do work
+ 11. The Consumer tries to pulls a message from the `Queue`
+ 12. If successful the message is put on the IO-buffer to be sent down the wire
+
+### Threading Model
+
+The consuming part is always invoked from the consuming connection's IO-Thread
+whereas the publishing part might be invoked from different threads (producing connection's
IO-Thread,
+Housekeeping thread for held or TTLed messages, a consuming connection's IO-Thread in case
for message reject).
+
+Therefore, the interfaces between `Consumers` and the `Queue` MUST be thread-safe and SHOULD
be lock free.
+
+### Interfaces Between Consumers and Queues
+
+These are the interfaces between `Consumers` and `Queues` and the scenarios when they are
called.
+
+  * `AbstractQueue#setNotifyWorkDesired`
+    Called by the `Consumer` to notify the `Queue` whether it is interested in doing work
or not.
+    * FlowControl
+    * Credit
+    * TCP backpressure
+  * `QueueConsumer#notifyWork`
+    Called by the `Queue` to notify the `Consumer` that there is potentially work available.
+    * Consumer becomes Interested
+    * A new message arrives
+    * A previously unavailable (acquired, held, blocked by message grouping) message becomes
available
+    * A notified consumer did not do the work we expected it to do we need to notify someone
else
+    * A high priority consumer becomes uninterested and thus allows a low priority consumer
to consume messages
+  * `AbstractQueue#deliverSingleMessage`
+    Called by the `Consumer` to get a message from the Queue.
+    * A consumer was notified and now tries to pull a message of a queue
+
+### QueueConsumerManager internals
+
+The `QueueConsumerManager` (QCM for short) keeps track of the state of `Consumers` from the
perspective of the `Queue`.
+It shares and decides which `Consumer` to notify of work with the `Queue`. To do this in
a performant way it maintains
+a number of lists and moves `Consumers` between those lists to indicate state change. The
lists it maintains are:
+
+  *  All (all queue consumers)
+  *  NonAcquiring
+  *  NotInterested
+  *  Interested
+  *  Notified
+
+Typically we want these lists to be thread-safe and give us O(1) access/deletion if we know
the element and O(1) size information.
+Unfortunately there is no data structure in the Java standard library with those characteristics
+which is why they are based on our own data structure `QueueConsumerNodeList`.
+
+#### QueueConsumerNodeList
+
+The `QueueConsumerNodeList` is the underlying data structure of all of QCM's lists.
+It is thread-safe and allows O(1) appending and given you have a pointer to an entry O(1)
deletion.
+It is essentially a singly linked list. To achieve O(1) deletion entries are marked for deletion
+but only actually removed upon the next iteration.  The rationale being that, to delete an
entry you would need
+to update the previous entry's "next" pointer but to get to the previous element you would
need a doubly linked list
+which it impossible to maintain in a thread-safe way without locking. Special care must be
taken when removing elements
+from the tail since we keep an explicit reference to it in the `QueueConsumerNodeList` to
achieve O(1) appending.
+The data structure in the `QueueConsumerNodeList` are called `QueueConsumerNodeListEntries`
which themselves have
+a reference to a `QueueConsumerNode` which is the persistent entity that moves between QCM's
lists and has a reference
+to the `QueueConsumer`. The `QueueConsumer` itself also has a reference to the `QueueConsumerNode`
to enable O(1)
+deletion given a Consumer. This tightly couples the `QueueConsumer` and QCM classes.
+
+#### The "All" List
+
+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.
+
+#### The "NonAcquiring" List
+
+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 `Consumer`s 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.
+
+#### The "Interested" List
+
+This is the default list for acquiring `Consumers`. It signifies that they are ready to process
messages.
+When a message becomes available, the `Queue` it will notify `Consumers` from this list and
move them to the
 
 Review comment:
   Done
 
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


> [Broker-J] Create a developer guide for Qpid Broker-J
> -----------------------------------------------------
>
>                 Key: QPID-8361
>                 URL: https://issues.apache.org/jira/browse/QPID-8361
>             Project: Qpid
>          Issue Type: Task
>          Components: Broker-J
>            Reporter: Alex Rudyy
>            Priority: Major
>             Fix For: qpid-java-broker-8.0.0
>
>
> The developer documentation is currently scattered over various Qpid confluence pages.
It could be challenging for people interested in contributing to the project to find that
documentation. A developer guide could be added to cover such aspects as
> * Environment Setup
> * Building project
> * Running tests
> * Releasing
> * Architecture overview
> The following wiki pages are good candidates for inclusion into a developer guide:
> [High Level Architecture|https://cwiki.apache.org/confluence/display/qpid/High+Level+Architecture]
> [How To Build Qpid Broker-J|https://cwiki.apache.org/confluence/display/qpid/How+To+Build+Qpid+Broker-J]
> [Releasing Qpid Broker-J|https://cwiki.apache.org/confluence/display/qpid/Releasing+Qpid+Broker-J]
> The wiki pages below might be included as well
> [Java Coding Standards|https://cwiki.apache.org/confluence/display/qpid/Java+Coding+Standards]
> [Qpid Java Run Scripts|https://cwiki.apache.org/confluence/display/qpid/Qpid+Java+Run+Scripts]
> The developer documentation should be easy to modify, maintain and preview. Thus, it
can be written in  markdown or [asciidoc|https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/].
The latter is also supported on github. 
> Potentially, it can be published on Qpid  project site as part of release process.



--
This message was sent by Atlassian Jira
(v8.3.2#803003)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Mime
View raw message