A high-level description of a proposed solution:
*) Use credit to prevent queue overflow event.
*) Associate watermarks with each Queue instance. Each queue would maintain a high and low watermark corresponding to a capacity level within the queue - the number of queued messages, for example, or the total number of message bytes enqueued. The watermarks would be constrained such that high_watermark >= low_watermark: the high_watermark would indicate the level of capacity at and above which the queue is considered likely to overflow. The low_watermark would indicate the level at or below which the queue is no longer considered likely to overflow.
*) Associate a state with each Queue instance that reflects the current level of data in the queue with respect to the watermarks. When the current level of data in the queue crosses the high_watermark, the state is set to "blocking". When the current level of data in the queue falls below the low_watermark, the state will transition to "normal" from "blocking"
*) Each message transferred to the broker will maintain a boolean "blocked" flag. After a message has been enqueued to all of the destination queues, the block flag will be set if one or more of the destination queues are in the blocking state.
*) The transfer of any message which has a set "blocked" flag will not be completed from the point of view of the client until the flag is reset.
*) A message's "blocked" flag will be reset when: 1) the state of all destination queues become "normal" or 2) the message is consumed from all queues.
*) The message is completed once the "blocked" flag is reset.
Issues with this approach:
1) the capacity level configured for a given producer must take into account the high_watermark setting of the potential destination queues. If the producer's capacity level is too high for a given queue (or the sum of all potential producer's capacity), the queue will overflow regardless of this solution.
2) A producer will be blocked based on the destination of the current set of outbound messages. A pending transfer of a message to a different - possibly unblocked - destination would be blocked by the current outstanding messages. This appears to be unavoidable given the 0.10 model.