Producer flow control commented on by Alan Conway (Jun 27, 2008).

Comment:

I've been kicking a bunch of ideas around on this front but none really grabs me yet. A key point here is that this debate really needs to happen at the AMQP working group, so that we can have an interoperable solution. Some things to think about:

1. AMQP already defines flow control to Exchanges, treating them identically to subscribers (both are referred to as "destinations" in the spec.) I feel like it should be possible to use this mechanism but there are some troubles:

A client subscription has exactly one "producer", i.e. the queue it is subscribed to. So it is easy to implement per-subscription flow policies, indeed we already do this - I think the java side calls it "prefetch".

An exchange on the other hand has many producers - any attached session can send messages to any exchange. We can control the flow to an exchange per session but this doesn't let us fix a limit for the exchange as a whole. It does let us throttle individual clients somewhat so it may provide some help, but its not straightforward to use it to implement an overall exchange flow rate policy. Its even harder to see how we could implement a queue policy as a queue may be bound in many exchanges and there's no way to predict in advance how much exchange traffic will go to any particular queue.

2. TCP flow control. In the absence of protocol methods for flow control, a simple technique is the following: if some session action would violate a policy, stop reading that sessions connection for up to some timeout period. If something happens (e.g. a message is dequeued) in that period that allows the problem session to proceed the action and start reading the connection again. If the action can't be handled within the timeout, kill the offending session and start reading the connection again.

Note the timeout above needs to be less that TCP's timeout or the client may disconnect the entire connection. A variation is to dispense with the timeout and let TCP decide the timeout, but in that case the entire connection will always be killed of the action can't be executed within TCP's timeout.

This could be considered a fall-back postion and combined with 1. above - we set exchange flow rates to values that we think are likely to avoid policy violations. Hopefully this works most of the time but if a violation is about to occur we fall back to 2 so our policies are respected.

3. New flow control commands: I'm not sure what ideal flow-control commands would look like. First thing to note: I think it is impossible in principal to guarantee per-queue policies will be respected using flow control commands alone. This is because messages are not sent to queues but to exchanges. The client does not know in general what queue(s) a message is going to so it cannot repsect per-queue limits. Remember that flow control depends on the producer volutarily limiting the number of messages it sends based on rules established in advance. Not knowing what queue a messages will go to means its impossible to establish per-queue flow limits on the client in advance. So there will always be a need for some fall-back position like 2 if there are per-queue policies.

I do think that flow control between a session and the broker as a whole would be more usable than flow control for each session/exchange pair. It would at allow the broker to use fixed-size input buffers per session and to enforce a total-queue-content limit.

Reply via email to