summaryrefslogtreecommitdiff
path: root/doc/book/src
diff options
context:
space:
mode:
authorStephen D. Huston <shuston@apache.org>2011-10-21 14:42:12 +0000
committerStephen D. Huston <shuston@apache.org>2011-10-21 14:42:12 +0000
commitf83677056891e436bf5ba99e79240df2a44528cd (patch)
tree625bfd644b948e89105630759cf6decb0435354d /doc/book/src
parentebfd9ff053b04ab379acfc0fefedee5a31b6d8a5 (diff)
downloadqpid-python-QPID-2519.tar.gz
Merged out from trunkQPID-2519
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/QPID-2519@1187375 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'doc/book/src')
-rw-r--r--doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml2
-rw-r--r--doc/book/src/AMQP-Messaging-Broker-CPP.xml4
-rw-r--r--doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml10
-rw-r--r--doc/book/src/Configure-Java-Qpid-to-use-a-SSL-connection.xml4
-rw-r--r--doc/book/src/Programming-In-Apache-Qpid.xml61
-rw-r--r--doc/book/src/Qpid-Java-FAQ.xml54
-rw-r--r--doc/book/src/Security.xml20
-rw-r--r--doc/book/src/System-Properties.xml70
-rw-r--r--doc/book/src/Using-message-groups.xml261
-rw-r--r--doc/book/src/producer-flow-control.xml351
10 files changed, 680 insertions, 157 deletions
diff --git a/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml b/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml
index 309492262d..10d83ec887 100644
--- a/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml
+++ b/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml
@@ -56,8 +56,10 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="LVQ.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="queue-state-replication.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Starting-a-cluster.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="producer-flow-control.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Compatibility.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Interoperability-Documentation.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Using-message-groups.xml"/>
</chapter>
diff --git a/doc/book/src/AMQP-Messaging-Broker-CPP.xml b/doc/book/src/AMQP-Messaging-Broker-CPP.xml
index b9c513e511..92b474b0c0 100644
--- a/doc/book/src/AMQP-Messaging-Broker-CPP.xml
+++ b/doc/book/src/AMQP-Messaging-Broker-CPP.xml
@@ -50,7 +50,9 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="LVQ.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="queue-state-replication.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Starting-a-cluster.xml"/>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ACL.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ACL.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="producer-flow-control.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Using-message-groups.xml"/>
</chapter>
diff --git a/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml b/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml
index 60f1a4103d..d50948e0cc 100644
--- a/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml
+++ b/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml
@@ -65,6 +65,16 @@
</itemizedlist>
</para></listitem>
</itemizedlist>
+
+ <para>
+ The 0.10 C++ Broker supports the following additional Queue configuration options:
+ </para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="producer-flow-control"/>
+ </para></listitem>
+ </itemizedlist>
+
<section role="h3" id="CheatSheetforconfiguringQueueOptions-ApplyingQueueSizingConstraints"><title>
Applying Queue Sizing Constraints
</title>
diff --git a/doc/book/src/Configure-Java-Qpid-to-use-a-SSL-connection.xml b/doc/book/src/Configure-Java-Qpid-to-use-a-SSL-connection.xml
index c09923711d..1ffd4b4050 100644
--- a/doc/book/src/Configure-Java-Qpid-to-use-a-SSL-connection.xml
+++ b/doc/book/src/Configure-Java-Qpid-to-use-a-SSL-connection.xml
@@ -51,8 +51,8 @@
&lt;ssl&gt;
&lt;enabled&gt;true&lt;/enabled&gt;
&lt;sslOnly&gt;true&lt;/sslOnly&gt;
- &lt;keystorePath&gt;/path/to/keystore.ks&lt;/keystorePath&gt;
- &lt;keystorePassword&gt;keystorepass&lt;/keystorePassword&gt;
+ &lt;keyStorePath&gt;/path/to/keystore.ks&lt;/keyStorePath&gt;
+ &lt;keyStorePassword&gt;keystorepass&lt;/keyStorePassword&gt;
&lt;/ssl&gt;
</programlisting>
diff --git a/doc/book/src/Programming-In-Apache-Qpid.xml b/doc/book/src/Programming-In-Apache-Qpid.xml
index 3950b375da..4d72864cb1 100644
--- a/doc/book/src/Programming-In-Apache-Qpid.xml
+++ b/doc/book/src/Programming-In-Apache-Qpid.xml
@@ -1722,7 +1722,7 @@ try {
<row>
<entry>
- username
+ <literal>username</literal>
</entry>
<entry>
string
@@ -1733,7 +1733,7 @@ try {
</row>
<row>
<entry>
- password
+ <literal>password</literal>
</entry>
<entry>
string
@@ -1744,35 +1744,22 @@ try {
</row>
<row>
<entry>
- sasl-mechanism
+ <literal>sasl_mechanisms</literal>
</entry>
<entry>
string
</entry>
<entry>
- The specific SASL mechanism to use with the c++
- client when authenticating to the broker. Only a
- single value can be specified at present. [C++ only].
- </entry>
- </row>
- <row>
- <entry>
- sasl_mechanisms
- </entry>
- <entry>
- string
- </entry>
- <entry>
- The specific SASL mechanism to use with the python
+ The specific SASL mechanisms to use with the python
client when authenticating to the broker. The value
- is a space separated list in order of preference. [Python only].
+ is a space separated list.
</entry>
</row>
<row>
<entry>
- reconnect
+ <literal>reconnect</literal>
</entry>
<entry>
boolean
@@ -1783,7 +1770,7 @@ try {
</row>
<row>
<entry>
- <literal>reconnect_timeout&nbsp;[Python]</literal> <literal>reconnect-timeout&nbsp;[C++]</literal>
+ <literal>reconnect_timeout</literal>
</entry>
<entry>
integer
@@ -1794,7 +1781,7 @@ try {
</row>
<row>
<entry>
- <literal>reconnect_limit&nbsp;[Python]</literal> <literal>reconnect-limit&nbsp;[C++]</literal>
+ <literal>reconnect_limit</literal>
</entry>
<entry>
integer
@@ -1805,7 +1792,7 @@ try {
</row>
<row>
<entry>
- <literal>reconnect_interval_min&nbsp;[Python]</literal> <literal>reconnect-interval-min&nbsp;[C++]</literal>
+ <literal>reconnect_interval_min</literal>
</entry>
<entry>
integer representing time in seconds
@@ -1816,7 +1803,7 @@ try {
</row>
<row>
<entry>
- <literal>reconnect_interval_max&nbsp;[Python]</literal> <literal>reconnect-interval-max&nbsp;[C++]</literal>
+ <literal>reconnect_interval_max</literal>
</entry>
<entry>
integer representing time in seconds
@@ -1827,7 +1814,7 @@ try {
</row>
<row>
<entry>
- <literal>reconnect_interval&nbsp;[Python]</literal> <literal>reconnect-interval&nbsp;[C++]</literal>
+ <literal>reconnect_interval</literal>
</entry>
<entry>
integer representing time in seconds
@@ -1839,7 +1826,7 @@ try {
<row>
<entry>
- heartbeat
+ <literal>heartbeat</literal>
</entry>
<entry>
integer representing time in seconds
@@ -1852,7 +1839,7 @@ try {
</row>
<row>
<entry>
- protocol
+ <literal>protocol</literal>
</entry>
<entry>
string
@@ -1863,7 +1850,7 @@ try {
</row>
<row>
<entry>
- tcp-nodelay
+ <literal>tcp-nodelay</literal>
</entry>
<entry>
boolean
@@ -3456,9 +3443,8 @@ log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n
<entry>qpid.amqp.version</entry>
<entry>string</entry>
<entry>0-10</entry>
- <entry>Sets the AMQP version to be used - currently supports one of {0-8,0-9,0-91,0-10}</entry>
- </row>
-
+ <entry><para>Sets the AMQP version to be used - currently supports one of {0-8,0-9,0-91,0-10}.</para><para>The client will begin negotiation at the specified version and only negotiate downwards if the Broker does not support the specified version.</para></entry>
+ </row>
<row>
<entry>qpid.heartbeat</entry>
<entry>int</entry>
@@ -3623,15 +3609,20 @@ log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n
<entry>qpid.transport</entry>
<entry>string</entry>
<entry>org.apache.qpid.transport.network.io.IoNetworkTransport</entry>
- <entry><para>The transport implementation to be used.</para><para>A user could specify an alternative transport mechanism that implements the <varname>org.apache.qpid.transport.network.NetworkTransport</varname> interface.</para></entry>
- </row>
-
+ <entry><para>The transport implementation to be used.</para><para>A user could specify an alternative transport mechanism that implements the <varname>org.apache.qpid.transport.network.NetworkTransport</varname> interface.</para></entry>
+ </row>
+ <row>
+ <entry>qpid.sync_op_timeout</entry>
+ <entry>long</entry>
+ <entry>60000</entry>
+ <entry><para>The length of time (in milliseconds) to wait for a synchronous operation to complete.</para><para>For compatibility with older clients, the synonym <varname>amqj.default_syncwrite_timeout</varname> is supported.</para></entry>
+ </row>
<row>
<entry>amqj.tcp_nodelay</entry>
<entry>boolean</entry>
<entry>false</entry>
- <entry><para>Sets the TCP_NODELAY property of the underlying socket.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
- </row>
+ <entry><para>Sets the TCP_NODELAY property of the underlying socket.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/doc/book/src/Qpid-Java-FAQ.xml b/doc/book/src/Qpid-Java-FAQ.xml
index 7a28703774..2144d3a533 100644
--- a/doc/book/src/Qpid-Java-FAQ.xml
+++ b/doc/book/src/Qpid-Java-FAQ.xml
@@ -736,35 +736,6 @@ amqj.logging.level
</para>
<!--h3--></section>
- <section role="h3" id="QpidJavaFAQ-HowdoIuseanInVMBrokerformyowntests-3F"><title>
- How do I
- use an InVM Broker for my own tests?
- </title>
-
- <para>
- I would take a look at the testPassiveTTL in
- <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java">TimeToLiveTest.java</ulink>
- </para><para>
- The setUp and tearDown methods show how to correctly start up a
- broker for InVM testing. If you write your tests using a file for
- the JNDI you can then very easily swap between running your tests
- InVM and against a real broker.
- </para><para>
- See our <xref linkend="How-to-Use-JNDI"/> on how to confgure it
- </para><para>
- Basically though you just need to set two System Properites:
- </para><para>
- java.naming.factory.initial =
- org.apache.qpid.jndi.PropertiesFileInitialContextFactory
- java.naming.provider.url = &lt;your JNDI file&gt;
- </para><para>
- and call getInitialContext() in your code.
- </para><para>
- You will of course need to have the broker libraries on your
- class path for this to run.
- </para>
-<!--h3--></section>
-
<section role="h3" id="QpidJavaFAQ-HowcanIinspectthecontentsofmyMessageStore-3F"><title>
How
can I inspect the contents of my MessageStore?
@@ -907,31 +878,6 @@ java.lang.NullPointerException
</para>
<!--h3--></section>
- <section role="h3" id="QpidJavaFAQ-Clientkeepsthrowing-27Serverdidnotrespondinatimelyfashion-27-5Cerrorcode408-3ARequestTimeout-5C."><title>
- Client keeps throwing 'Server did not respond in a timely
- fashion' [error code 408: Request Timeout].
- </title>
-
- <para>
- Certain operations wait for a response from the Server. One such
- operations is commit. If the server does not respond to the
- commit request within a set time a Request Timeout [error code:
- 408] exception is thrown (Server did not respond in a timely
- fashion). This is to ensure that a server that has hung does not
- cause the client process to be come unresponsive.
- </para><para>
- However, it is possible that the server just needs a long time to
- process a give request. For example, sending a large persistent
- message when using a persistent store will take some time to a)
- Transfer accross the network and b) to be fully written to disk.
- </para><para>
- These situations require that the default timeout value be
- increased. A cilent <xref linkend="qpid_System-Properties"/> 'amqj.default_syncwrite_timeout' can be set
- on the client to increase the wait time. The default in 0.5 is
- 30000 (30s).
- </para>
-<!--h3--></section>
-
<section role="h3" id="QpidJavaFAQ-CanauseTCPKEEPALIVEorAMQPheartbeatingtokeepmyconnectionopen-3F"><title>
Can a use TCP_KEEPALIVE or AMQP heartbeating to keep my
connection open?
diff --git a/doc/book/src/Security.xml b/doc/book/src/Security.xml
index 77d10abf8c..49abfbebca 100644
--- a/doc/book/src/Security.xml
+++ b/doc/book/src/Security.xml
@@ -1,5 +1,25 @@
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
<section id="chap-Messaging_User_Guide-Security">
<title>Security</title>
<para>
diff --git a/doc/book/src/System-Properties.xml b/doc/book/src/System-Properties.xml
index d61673f234..40b823185f 100644
--- a/doc/book/src/System-Properties.xml
+++ b/doc/book/src/System-Properties.xml
@@ -135,7 +135,7 @@
<varlistentry>
- <term>amqj.default_syncwrite_timeout</term>
+ <term>qpid.sync_op_timeout</term>
<listitem>
<variablelist>
<varlistentry>
@@ -144,12 +144,11 @@
</varlistentry>
<varlistentry>
<term>Default</term>
- <listitem><para>30000</para></listitem>
+ <listitem><para>60000</para></listitem>
</varlistentry>
</variablelist>
- <para> The number length of time in millisecond to wait
- for a synchronous write to complete.
- </para>
+ <para>The length of time (in milliseconds) to wait for a synchronous operation to complete.
+ For compatibility with older clients, the synonym amqj.default_syncwrite_timeout is supported.</para>
</listitem>
</varlistentry>
@@ -193,7 +192,7 @@
<varlistentry>
- <term>amqj.tcpNoDelay</term>
+ <term>amqj.tcp_nodelay</term>
<listitem>
<variablelist>
<varlistentry>
@@ -211,65 +210,6 @@
</varlistentry>
<varlistentry>
- <term>amqj.sendBufferSize</term>
- <listitem>
- <variablelist>
- <varlistentry>
- <term>integer</term>
- <listitem><para>Boolean</para></listitem>
- </varlistentry>
- <varlistentry>
- <term>Default</term>
- <listitem><para>32768</para></listitem>
- </varlistentry>
- </variablelist>
- <para>This is the default buffer sized created by Mina.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>amqj.receiveBufferSize</term>
- <listitem>
- <variablelist>
- <varlistentry>
- <term>Type</term>
- <listitem><para>integer</para></listitem>
- </varlistentry>
- <varlistentry>
- <term>Default</term>
- <listitem><para>32768</para></listitem>
- </varlistentry>
- </variablelist>
- <para>This is the default buffer sized created by Mina.
- </para>
- </listitem>
- </varlistentry>
-
-
- <varlistentry>
- <term>amqj.protocolprovider.class</term>
- <listitem>
- <variablelist>
- <varlistentry>
- <term>Type</term>
- <listitem><para>String</para></listitem>
- </varlistentry>
- <varlistentry>
- <term>Default</term>
- <listitem><para>org.apache.qpid.server.protocol.AMQPFastProtocolHandler</para></listitem>
- </varlistentry>
- </variablelist>
- <para> This specifies the default IoHandlerAdapter that
- represents the InVM broker. The IoHandlerAdapter must have
- a constructor that takes a single Integer that represents
- the InVM port number.
- </para>
- </listitem>
- </varlistentry>
-
-
- <varlistentry>
<term>amqj.protocol.logging.level</term>
<listitem>
<variablelist>
diff --git a/doc/book/src/Using-message-groups.xml b/doc/book/src/Using-message-groups.xml
new file mode 100644
index 0000000000..7de7fbb995
--- /dev/null
+++ b/doc/book/src/Using-message-groups.xml
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<section id="Using-message-groups">
+ <title>
+ Using Message Groups
+ </title>
+
+ <section role="h2" id="usingmessagegroups-Overview">
+ <title>
+ Overview
+ </title>
+ <para>
+ The broker allows messaging applications to classify a set of related messages as
+ belonging to a group. This allows a message producer to indicate to the consumer
+ that a group of messages should be considered a single logical operation with
+ respect to the application.
+ </para>
+ <para>
+ The broker can use this group identification to enforce policies controlling how
+ messages from a given group can be distributed to consumers. For instance, the
+ broker can be configured to guarantee all the messages from a particular group are
+ processed in order across multiple consumers.
+ </para>
+ <para>
+ For example, assume we have a shopping application that manages items in a virtual
+ shopping cart. A user may add an item to their shopping cart, then change their
+ mind and remove it. If the application sends an <emphasis>add</emphasis> message to the broker,
+ immediately followed by a <emphasis>remove</emphasis> message, they will be queued in the proper
+ order - <emphasis>add</emphasis>, followed by <emphasis>remove</emphasis>.
+ </para>
+ <para>
+ However, if there are multiple consumers, it is possible that once a consumer
+ acquires the <emphasis>add</emphasis> message, a different consumer may acquire the
+ <emphasis>remove</emphasis> message. This allows both messages to be processed in parallel,
+ which could result in a "race" where the <emphasis>remove</emphasis> operation is incorrectly
+ performed before the <emphasis>add</emphasis> operation.
+ </para>
+ </section>
+ <!--h2-->
+ <section role="h2" id="usingmessagegroups-GroupingMessages">
+ <title>
+ Grouping Messages
+ </title>
+ <para>
+ In order to group messages, the application would designate a particular
+ application header as containing a message's <emphasis>group identifier</emphasis>. The group
+ identifier stored in that header field would be a string value set by the message
+ producer. Messages from the same group would have the same group identifier
+ value. The key that identifies the header must also be known to the message
+ consumers. This allows the consumers to determine a message's assigned group.
+ </para>
+ <para>
+ The header that is used to hold the group identifier, as well as the values used
+ as group identifiers, are totally under control of the application.
+ </para>
+ </section>
+ <section role="h2" id="usingmessagegroups-BrokerRole">
+ <title>
+ The Role of the Broker
+ </title>
+ <para>
+ The broker will apply the following processing on each grouped message:
+ <itemizedlist>
+ <listitem>Enqueue a received message on the destination queue.</listitem>
+ <listitem>Determine the message's group by examining the message's group identifier header.</listitem>
+ <listitem>Enforce <emphasis>consumption ordering</emphasis> among messages belonging to the same group.</listitem>
+ </itemizedlist>
+ <emphasis>Consumption ordering</emphasis> means that the broker will not allow outstanding
+ unacknowledged messages to <emphasis>more than one consumer for a given group</emphasis>.
+ </para>
+ <para>
+ This means that only one consumer can be processing messages from a particular
+ group at a given time. When the consumer acknowledges all of its acquired
+ messages, then the broker <emphasis>may</emphasis> pass the next message from that group to
+ another consumer.
+ </para>
+ <para>
+ Specifically, for any given group, the broker allows only the first N messages in
+ the group to be available for delivery to a particular consumer. The value of N
+ would be determined by the selected consumer's configured prefetch capacity. The
+ broker blocks access to the remaining messages in that group by any other
+ consumer. Once the selected consumer has acknowledged that first set of delivered
+ messages, the broker allows the next messages in the group to be available for
+ delivery. The next set of messages may be delivered to a different consumer.
+ </para>
+ <para>
+ Note well that distinct message groups would not block each other from delivery.
+ For example, assume a queue contains messages from two different message groups -
+ say group "A" and group "B" - and they are enqueued such that "A"'s messages are
+ in front of "B". If the first message of group "A" is in the process of being
+ consumed by a client, then the remaining "A" messages are blocked, but the
+ messages of the "B" group are available for consumption by other consumers - even
+ though it is "behind" group "A" in the queue.
+ </para>
+ </section>
+ <section role="h2" id="usingmessagegroups-ConsumerGuide">
+ <title>
+ Well Behaved Consumers
+ </title>
+ <para>
+ In order to guarantee the ordering policy, the consuming application has to ensure
+ that it has completely processed the data in a received message before accepting
+ that message, as described in Section 2.6.2. Transfer of Responsibility, of the
+ AMQP-0.10 specification.
+ </para>
+ <para>
+ The term <emphasis>processed</emphasis> means that the application has finished updating all
+ state related to the message that has been received.
+ </para>
+ <note>
+ <title>Be Advised</title>
+ <para>
+ It is possible for a consumer to affect the ordering of grouped messages even
+ when the broker is enforcing consumption order. This can be done by selectively
+ acknowledging and releasing messages from the same group.
+ </para>
+ <para>
+ Assume a consumer has received two messages from group "A", "A-1" and "A-2", in
+ that order. If the consumer releases "A-1" then acknowledges "A-2", "A-1" will
+ be put back onto the queue and "A-2" will be removed from the queue. This
+ allows another consumer to acquire and process "A-1" <emphasis>after</emphasis> "A-2" has been
+ processed.
+ </para>
+ <para>
+ Under some application-defined circumstances, this may be acceptable behavior.
+ However, if order must be preserved, the client should either release <emphasis>all</emphasis>
+ currently held messages, or discard the target message using reject.
+ </para>
+ </note>
+ </section>
+ <!--h2-->
+ <section role="h2" id="usingmessagegroups-BrokerConfig">
+ <title>
+ Broker Configuration
+ </title>
+ <para>
+ In order for the broker to determine a message's group, the key for the header
+ that contains the group identifier must be provided to the broker via
+ configuration. This is done on a per-queue basis, when the queue is first
+ configured.
+ </para>
+ <para>
+ This means that message group classification is determined by the message's destination
+ queue.
+ </para>
+ <para>
+ Specifically, the queue "holds" the header key that is used to find the message's
+ group identifier. All messages arriving at the queue are expected to use the same
+ header key for holding the identifer. Once the message is enqueued, the broker
+ looks up the group identifier in the message's header, and classifies the message
+ by its group.
+ </para>
+ <para>
+ Message group support can be enabled on a queue using the
+ <command>qpid-config</command> command line tool. The following options should be
+ provided when adding a new queue:
+ <programlisting>
+ --group-header=<replaceable>header-name</replaceable> Enable message group support for this queue. Specify name of application header that holds the group identifier.
+ --shared-groups Enforce ordered message group consumption across multiple consumers.
+ </programlisting>
+ </para>
+ <para>
+ Message group support may also be specified in the
+ <command>queue.declare</command> method via the <command>arguments</command>
+ parameter map, or using the messaging address syntax. The following keys must be
+ provided in the arguments map to enable message group support on a queue:
+ </para>
+ <table>
+ <title>Queue Declare/Addres Syntax Message Group Configuration Arguments</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Key</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>qpid.group_header_key</entry>
+ <entry>string - key for message header that holds the group identifier value</entry>
+ </row>
+ <row>
+ <entry>qpid.shared_msg_group</entry>
+ <entry>1 - enforce ordering across multiple consumers</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ It is important to note that there is no need to provide the actual group
+ identifer values that will be used. The broker learns this values as messages are
+ recieved. Also, there is no practical limit - aside from resource limitations -
+ to the number of different groups that the broker can track at run time.
+ </para>
+ <note>
+ <title>Restrictions</title>
+ <para>
+ Message grouping is not supported on LVQ or Priority queues.
+ </para>
+ </note>
+ <example>
+ <title>Creating a message group queue via qpid-config</title>
+ <para>
+ This example uses the qpid-config tool to create a message group queue called
+ "MyMsgQueue". The message header that contains the group identifier will use
+ the key "GROUP_KEY".
+ </para>
+ <programlisting>
+ qpid-config add queue MyMsgQueue --group-header="GROUP_KEY" --shared-groups"
+ </programlisting>
+ </example>
+ <example>
+ <title>Creating a message group queue using address syntax (C++)</title>
+ <para>
+ This example uses the messaging address syntax to create a message group queue
+ with the same configuration as the previous example.
+ </para>
+ <programlisting>
+ sender = session.createSender("MyMsgQueue; {create:always, delete:receiver, node: {x-declare: {arguments:"
+ " {'qpid.group_header_key':'GROUP_KEY', 'qpid.shared_msg_group':1}}}}")
+ </programlisting>
+ </example>
+ <section role="h3" id="usingmessagegroups-DefaultGroup">
+ <title>
+ Default Group
+ </title>
+ <para>
+ Should a message without a group identifier arrive at a queue configured for message grouping, the broker assigns the message to the default group. Therefore, all such "unidentified" messages are considered by the broker as part of the same group. The name of the default group is <command>"qpid.no-group"</command>. This default can be overridden by suppling a different value to the broker configuration item <command>"default-message-group"</command>:
+ <example>
+ <title>Overriding the default message group identifier for the broker</title>
+ <programlisting>
+ qpidd --default-msg-group "EMPTY-GROUP"
+ </programlisting>
+ </example>
+ </para>
+ </section>
+ </section>
+ </section>
+
+
+
diff --git a/doc/book/src/producer-flow-control.xml b/doc/book/src/producer-flow-control.xml
new file mode 100644
index 0000000000..fd44f51e81
--- /dev/null
+++ b/doc/book/src/producer-flow-control.xml
@@ -0,0 +1,351 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<section id="producer-flow-control">
+ <title>
+ Producer Flow Control
+ </title>
+
+ <section role="h2" id="producerflowcontrol-Overview">
+ <title>
+ Overview
+ </title>
+ <para>
+ As of release 0.10, the C++ broker supports the use of flow control to
+ throttle back message producers that are at risk of overflowing a
+ destination queue.
+ </para>
+
+ <para>
+ Each queue in the C++ broker has two threshold values associated with it:
+ </para>
+
+ <para>
+ Flow Stop Threshold: this is the level of queue resource
+ utilization above which flow control will be enabled. Once this
+ threshold is crossed, the queue is considered in danger of overflow.
+ </para>
+
+ <para>
+ Flow Resume Threshold - this is the level of queue resource utilization
+ below which flow control will be disabled. Once this threshold is
+ crossed, the queue is no longer considered in danger of overflow.
+ </para>
+
+ <para>
+ In the above description, queue resource utilization may be
+ defined as the total count of messages currently enqueued, or the total
+ sum of all message content in bytes.
+ </para>
+
+ <para>
+ The value for a queue's Flow Stop Threshold must be greater than or
+ equal to the value of the queue's Flow Resume Threshold.
+ </para>
+
+ <section role="h3" id="producerflowcontrol-QueueThresholdsExample">
+ <title>
+ Example
+ </title>
+
+ <para>
+ Let's consider a queue with a maximum limit set on the total number of
+ messages that may be enqueued to that queue. Assume this maximum
+ message limit is 1000 messages. Assume also that the user configures a
+ Flow Stop Threshold of 900 messages, and a Flow Resume Threshold of 500
+ messages. Then the following holds:
+ </para>
+
+ <para>
+ The queue's initial flow control state is "OFF".
+ </para>
+
+ <para>
+ While the total number of enqueued messages is less than or equal to
+ 900, the queue's flow control state remains "OFF".
+ </para>
+
+ <para>
+ When the total number of enqueued messages is greater than 900, the
+ queue's flow control state transitions to "ON".
+ </para>
+
+ <para>
+ When the queue's flow control state is "ON", it remains "ON" until the
+ total number of enqueued messages is less than 500. At that point, the queue's
+ flow control state transitions to "OFF".
+ </para>
+
+ <para>
+ A similar example using total enqueued content bytes as the threshold
+ units are permitted.
+ </para>
+ </section>
+
+ <para>
+ Thresholds may be set using both total message counts and total byte
+ counts. In this case, the following rules apply:
+ </para>
+
+ <para>
+ 1) Flow control is "ON" when either stop threshold value is crossed.
+ </para>
+ <para>
+ 2) Flow control remains "ON" until both resume thresholds are satisfied.
+ </para>
+
+ <section role="h3" id="producerflowcontro-MultiThresholdExample">
+ <title>
+ Example
+ </title>
+
+ <para>
+ Let's consider a queue with a maximum size limit of 10K bytes, and 5000
+ messages. A user may assign a Flow Stop Threshold based on a total
+ message count of 4000 messages. They may also assigne a Flow Stop
+ Threshold of 8K bytes. The queue's flow control state transitions to
+ "ON" if either threshold is crossed: (total-msgs greater-than 4000 OR total-bytes
+ greater-than 8K).
+ </para>
+
+ <para>
+ Assume the user has assigned Flow Resume threshold's of 3000 messages and
+ 6K bytes. Then the queue's flow control will remain active until both
+ thresholds are satified: (total-msg less-than 3000 AND total-bytes less-than 6K).
+ </para>
+ </section>
+
+ <para>
+ The Broker enforces flow control by delaying the completion of the
+ Message.Transfer command that causes a message to be delivered to a queue
+ with active flow control. The completion of the Message.Transfer command
+ is held off until flow control state transitions to "OFF" for all queues
+ that are a destination for that command.
+ </para>
+
+ <para>
+ A message producing client is permitted to have a finite number of
+ commands pending completion. When the total number of these outstanding
+ commands reaches the limit, the client must not issue further commands
+ until one or more of the outstanding commands have completed. This
+ window of outstanding commands is considered the sender's "capacity".
+ This allows any given producer to have a "capacity's" worth of messages
+ blocked due to flow control before the sender must stop sending further
+ messages.
+ </para>
+
+ <para>
+ This capacity window must be considered when determining a suitable
+ flow stop threshold for a given queue, as a producer may send its
+ capacity worth of messages _after_ a queue has reached the flow stop
+ threshold. Therefore, a flow stop threshould should be set such that
+ the queue can accomodate more messages without overflowing.
+ </para>
+
+ <para>
+ For example, assume two clients, C1 and C2, are producing messages to
+ one particular destination queue. Assume client C1 has a configured
+ capacity of 50 messages, and client C2's capacity is 15 messages. In
+ this example, assume C1 and C2 are the only clients queuing messages to
+ a given queue. If this queue has a Flow Stop Threshold of 100
+ messages, then, worst-case, the queue may receive up to 165 messages
+ before clients C1 and C2 are blocked from sending further messages.
+ This is due to the fact that the queue will enable flow control on
+ receipt of its 101'st message - preventing the completion of the
+ Message.Transfer command that carried the 101'st message. However, C1
+ and C2 are allowed to have a total of 65 (50 for C1 and 15 for C2)
+ messages pending completion of Message.Transfer before they will stop
+ producing messages. Thus, up to 65 messages may be enqueued beyond the
+ flow stop threshold before the producers will be blocked.
+ </para>
+ </section>
+
+ <section role="h2" id="producerflowcontrol-UserInterface">
+ <title>
+ User Interface
+ </title>
+
+ <para>
+ By default, the C++ broker assigns a queue's flow stop and flow resume
+ thresholds when the queue is created. The C++ broker also allows the
+ user to manually specify the flow control thresholds on a per queue
+ basis.
+ </para>
+
+ <para>
+ However, queues that have been configured with a Limit Policy of type
+ RING or RING-STRICT do NOT have queue flow thresholds enabled by
+ default. The nature of a RING queue defines its behavior when its
+ capacity is reach: replace the oldest message.
+ </para>
+
+ <para>
+ The flow control state of a queue can be determined by the "flowState"
+ boolean in the queue's QMF management object. The queue's management
+ object also contains a counter that increments each time flow control
+ becomes active for the queue.
+ </para>
+
+ <para>
+ The broker applies a threshold ratio to compute a queue's default flow
+ control configuration. These thresholds are expressed as a percentage
+ of a queue's maximum capacity. There is one value for determining the
+ stop threshold, and another for determining the resume threshold. The
+ user may configure these percentages using the following broker
+ configuration options:
+ </para>
+
+ <programlisting>
+ --default-flow-stop-threshold ("Queue capacity level at which flow control is activated.")
+ --default-flow-resume-threshold ("Queue capacity level at which flow control is de-activated.")
+ </programlisting>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>
+ qpidd --default-flow-stop-threshold=90 --default-flow-resume-threshold=75
+ </programlisting>
+
+ <para>
+ Sets the default flow stop threshold to 90% of a queue's maximum
+ capacity and the flow resume threshold to 75% of the maximum capacity.
+ If a queue is created with a default-queue-limit of 10000 bytes, then
+ the default flow stop threshold would be 90% of 10000 = 9000 bytes and
+ the flow resume threshold would be 75% of 10000 = 7500. The same
+ computation is performed should a queue be created with a maximum size
+ expressed as a message count instead of a byte count.
+ </para>
+
+ <para>
+ If not overridden by the user, the value of the
+ default-flow-stop-threshold is 80% and the value of the
+ default-flow-resume-threshold is 70%.
+ </para>
+
+ <para>
+ The user may disable default queue flow control broker-wide by
+ specifying the value 0 for both of these configuration options. Note
+ that flow control may still be applied manually on a per-queue basis in
+ this case.
+ </para>
+
+ <para>
+ The user may manually set the flow thresholds when creating a queue.
+ The following options may be provided when adding a queue using the
+ <command>qpid-config</command> command line tool:
+ </para>
+
+ <programlisting>
+ --flow-stop-size=<replaceable>N</replaceable> Sets the queue's flow stop threshold to <replaceable>N</replaceable> total bytes.
+ --flow-resume-size=<replaceable>N</replaceable> Sets the queue's flow resume threshold to <replaceable>N</replaceable> total bytes.
+ --flow-stop-count=<replaceable>N</replaceable> Sets the queue's flow stop threshold to <replaceable>N</replaceable> total messages.
+ --flow-resume-count=<replaceable>N</replaceable> Sets the queue's flow resume threshold to <replaceable>N</replaceable> total messages.
+ </programlisting>
+
+ <para>
+ Flow thresholds may also be specified in the
+ <command>queue.declare</command> method, via the
+ <command>arguments</command> parameter map. The following keys can be
+ provided in the arguments map for setting flow thresholds:
+ </para>
+
+ <table>
+ <title>Queue Declare Method Flow Control Arguments</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Key</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>qpid.flow_stop_size</entry>
+ <entry>integer - queue's flow stop threshold value in bytes</entry>
+ </row>
+ <row>
+ <entry>qpid.flow_resume_size</entry>
+ <entry>integer - queue's flow resume threshold value in bytes</entry>
+ </row>
+ <row>
+ <entry>qpid.flow_stop_count</entry>
+ <entry>integer - queue's flow stop threshold value as a message count</entry>
+ </row>
+ <row>
+ <entry>qpid.flow_resume_count</entry>
+ <entry>integer - queue's flow resume threshold value as a message count</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The user may disable flow control on a per queue basis by setting
+ the flow-stop-size and flow-stop-count to zero for the queue.
+ </para>
+
+ <para>
+ The current state of flow control for a given queue can be
+ determined by the "flowStopped" statistic. This statistic is
+ available in the queue's QMF management object. The value of
+ flowStopped is True when the queue's capacity has exceeded the
+ flow stop threshold. The value of flowStopped is False when the
+ queue is no longer blocking due to flow control.
+ </para>
+
+ <para>
+ A queue will also track the number of times flow control has been
+ activated. The "flowStoppedCount" statistic is incremented each time
+ the queue's capacity exceeds a flow stop threshold. This statistic can
+ be used to monitor the activity of flow control for any given queue
+ over time.
+ </para>
+
+ <table>
+ <title>Flow Control Statistics available in Queue's QMF Class</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Statistic Name</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>flowStopped</entry>
+ <entry>Boolean</entry>
+ <entry>If true, producers are blocked by flow control.</entry>
+ </row>
+ <row>
+ <entry>flowStoppedCount</entry>
+ <entry>count32</entry>
+ <entry>Number of times flow control was activated for this queue</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <!--h2-->
+ </section>