<div>Matthew, Alvaro,</div><div><div><br></div><div>thanks for your answers and your reactivity!</div><div><br></div><div>I understand that the "mandatory" feature definitely lacks flexibility to be used for one-to-many communications and that there is no easy workaround.</div>
<div><br></div><div>The "non auto-delete, non exclusive queue" solution would not be suitable to my case, I really need messages to be dropped, and the sender to be alerted. The Smart Proxy approach is interesting, but doesn't seem compatible with the use of the mandatory flag, and the return alerts associated.</div>
<div><br></div><div>I've managed - with 10 lines of erlang - to let queues have an additional boolean "spy" parameter, and have the "spy" queues deliver the mandatory messages without this counting as a correct delivery, from the router point of view. Twisted, but it's working. (and it's much simpler than having "spy" bindings, the routing and delivery being two separated mechanisms).</div>
<div><br></div><div>My modifications:</div><div><br></div><div><div><i><span class="Apple-style-span" style="font-style: normal; "><b>rabbit.hrl :</b></span></i></div><div><i>(edition of the amqqueue record, line 47)</i></div>
<div><i><br></i></div><div><div> -record(amqqueue, {name, durable, auto_delete, exclusive_owner = none, <font class="Apple-style-span" color="#CC0000">spy=false,</font></div><div> arguments, pid}).</div>
</div></div><div><br></div><div><br></div><div><b>rabbit_amqqueue.erl :</b></div><div><i><br></i></div><div><i>(line 115, spec of deliver/2 edited )</i></div><blockquote class="webkit-indent-blockquote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">
<div><i> -spec(deliver/2 :: (pid(), rabbit_types:delivery()) -> boolean()<font class="Apple-style-span" color="#CC0000">|spy</font>).</i></div></blockquote><div><i><br></i></div><div><i>(edition of rabbit_amqqueue:declare)</i></div>
<blockquote class="webkit-indent-blockquote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">
<div><div>declare(QueueName, Durable, AutoDelete, Args, Owner) -></div></div><div><div> ok = check_declare_arguments(QueueName, Args),</div></div><div><div> Q = start_queue_process(#amqqueue{name = QueueName,</div>
</div><div><div> durable = Durable,</div></div><div><div> auto_delete = AutoDelete,</div></div><div><div> arguments = Args,</div>
</div><div><div> <font class="Apple-style-span" color="#CC0000">spy = case lists:keyfind(<<"spy">>, 1, Args) of</font></div><div><font class="Apple-style-span" color="#CC0000"> false -> false;</font></div>
<div><font class="Apple-style-span" color="#CC0000"> _ -> true</font></div><div><font class="Apple-style-span" color="#CC0000"> end,</font></div>
</div><div><div> exclusive_owner = Owner,</div></div><div><div> pid = none}),</div></div><div><div> case gen_server2:call(Q#amqqueue.pid, {init, false}, infinity) of</div>
</div><div><div> not_found -> rabbit_misc:not_found(QueueName);</div></div><div><div> Q1 -> Q1</div></div><div><div> end.</div></div></blockquote><div><br></div><div><i>(edition of rabbit_amqqueue:deliver/2)</i></div>
<div><i><br></i></div><div><div> deliver(QPid, Delivery = #delivery{immediate = true}) -></div><div> gen_server2:call(QPid, {deliver_immediately, Delivery}, infinity);</div><div> deliver(QPid, Delivery = #delivery{mandatory = true}) -></div>
<div> <font class="Apple-style-span" color="#CC0000">case gen_server2:call(QPid, {deliver, Delivery}, infinity) of</font></div><div><font class="Apple-style-span" color="#CC0000"> spy -> spy;</font></div>
<div><font class="Apple-style-span" color="#CC0000"> _ -> true</font></div><div><font class="Apple-style-span" color="#CC0000"> end;</font></div><div> deliver(QPid, Delivery) -></div><div>
gen_server2:cast(QPid, {deliver, Delivery}),</div><div> true.</div></div><div><br></div><div><br></div><div><i><span class="Apple-style-span" style="font-style: normal; "><b>rabbit_amqqueue_router.erl :</b></span></i></div>
</div><div><i>(edition of rabbit_router:fold_deliveries/2, line 105)</i></div><div><div><br></div><div> fold_deliveries({Pid, true},{_, Handled}) -> {true, [Pid|Handled]};</div><div><font class="Apple-style-span" color="#CC0000"> fold_deliveries({_, spy}, {false, Handled}) -> {false, Handled};</font></div>
<div> fold_deliveries({_, _},{_, Handled}) -> {true, Handled}.</div></div><div><br></div><div><br></div><div>For the moment, I think I'll go with this :)</div><div>Thanks again for your help.</div><div><br></div>
<div>Charly</div><div><b><br></b></div><div><br><div class="gmail_quote">On Thu, Mar 24, 2011 at 4:16 PM, Alvaro Videla <span dir="ltr"><<a href="mailto:videlalvaro@gmail.com" target="_blank">videlalvaro@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi,<br>
<br>
For spying messages on an RPC setup I'm working on an implementation of the Smart Proxy messaging pattern: <a href="http://www.eaipatterns.com/SmartProxy.html" target="_blank">http://www.eaipatterns.com/SmartProxy.html</a> perhaps you could implement that too.<br>
<br>
This is what I've done so far: <a href="http://vimeo.com/20966661" target="_blank">http://vimeo.com/20966661</a> which is at early stage of development and very alpha.<br>
<br>
Also take a look at the Wire Tap messaging pattern: <a href="http://www.eaipatterns.com/WireTap.html" target="_blank">http://www.eaipatterns.com/WireTap.html</a><br>
<br>
I guess most of the patterns from that book can be implemented with RabbitMQ, and some of them are already there but with different nomenclature.<br>
<br>
Hope this helps,<br>
<font color="#888888"><br>
Alvaro<br>
</font><div><div></div><div><br>
On Mar 24, 2011, at 4:05 PM, Matthew Sackman wrote:<br>
<br>
> Hi Charly,<br>
><br>
> On Thu, Mar 24, 2011 at 03:35:35PM +0100, Charly Hamy wrote:<br>
>> For the req/res scenario, I'm using the mandatory flag on my messages, so<br>
>> that sending a request message to a disconnected component (no corresponding<br>
>> queue declared on the broker) returns an error to the sender. This works as<br>
>> expected.<br>
><br>
> Well... you're using mandatory as a poor-man's form of resource<br>
> monitoring.<br>
><br>
>> But now, I would want to plug new components to spy on those flows of<br>
>> requests and responses, without interfering with the ongoing<br>
>> communications... which is not by default compatible with my use of the<br>
>> mandatory flag : when a "spy" component is monitorng request/response<br>
>> messages, those messages end-up in its queue, then even if the actual target<br>
>> component for those messages is not present on the broker (no queue), no<br>
>> error is returned to the sender.<br>
><br>
> Indeed, which is why mandatory is probably a mis-feature and should not<br>
> be used. Basically, AMQP does not really provide any sort of sane<br>
> resource monitoring. We've added in the 2.4.0 release consumer-death<br>
> notifications, but that's not going to help you here. You really have a<br>
> choice: make the queue non-exclusive and non-autodelete. Thus it always<br>
> stays there and will always receive messages. Then, you have your<br>
> clients just consume from it. The queue will do round-robining between<br>
> the consumers and all should be well, but you might have reasons why you<br>
> want the queue to be exclusive or autodelete. The other option is to use<br>
> some other tool to do monitoring of your consumers and to address that<br>
> problem outside of AMQP/RabbitMQ.<br>
><br>
> Best wishes,<br>
><br>
> Matthew<br>
> _______________________________________________<br>
> rabbitmq-discuss mailing list<br>
> <a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.rabbitmq.com</a><br>
> <a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss</a><br>
<br>
_______________________________________________<br>
rabbitmq-discuss mailing list<br>
<a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.rabbitmq.com</a><br>
<a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss</a><br>
</div></div></blockquote></div><br></div>