<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 &quot;mandatory&quot; 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 &quot;non auto-delete, non exclusive queue&quot; 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&#39;t seem compatible with the use of the mandatory flag, and the return alerts associated.</div>
<div><br></div><div>I&#39;ve managed - with 10 lines of erlang - to let queues have an additional boolean &quot;spy&quot; parameter, and have the &quot;spy&quot; queues deliver the mandatory messages without this counting as a correct delivery, from the router point of view. Twisted, but it&#39;s working. (and it&#39;s much simpler than having &quot;spy&quot; 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()) -&gt; 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) -&gt;</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(&lt;&lt;&quot;spy&quot;&gt;&gt;, 1, Args) of</font></div><div><font class="Apple-style-span" color="#CC0000">�� � � � � � � � � � � � � � � � � � � � � � false -&gt; false;</font></div>
<div><font class="Apple-style-span" color="#CC0000">�� � � � � � � � � � � � � � � � � � � � � � _ -&gt; 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 -&gt; rabbit_misc:not_found(QueueName);</div></div><div><div>�� � � �Q1 � � � �-&gt; 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}) -&gt;</div><div>�� � � � �gen_server2:call(QPid, {deliver_immediately, Delivery}, infinity);</div><div>�� � deliver(QPid, Delivery = #delivery{mandatory = true}) -&gt;</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 -&gt; spy;</font></div>
<div><font class="Apple-style-span" color="#CC0000">�� � � � � � � _ -&gt; true</font></div><div><font class="Apple-style-span" color="#CC0000">�� � � � �end;</font></div><div>�� � deliver(QPid, Delivery) -&gt;</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}) -&gt; {true, [Pid|Handled]};</div><div><font class="Apple-style-span" color="#CC0000">�� � fold_deliveries({_, �spy}, {false, Handled}) -&gt; {false, Handled};</font></div>
<div>�� � fold_deliveries({_, �_},{_, Handled}) -&gt; {true, Handled}.</div></div><div><br></div><div><br></div><div>For the moment, I think I&#39;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">&lt;<a href="mailto:videlalvaro@gmail.com" target="_blank">videlalvaro@gmail.com</a>&gt;</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&#39;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&#39;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>
&gt; Hi Charly,<br>
&gt;<br>
&gt; On Thu, Mar 24, 2011 at 03:35:35PM +0100, Charly Hamy wrote:<br>
&gt;&gt; For the req/res scenario, I&#39;m using the mandatory flag on my messages, so<br>
&gt;&gt; that sending a request message to a disconnected component (no corresponding<br>
&gt;&gt; queue declared on the broker) returns an error to the sender. This works as<br>
&gt;&gt; expected.<br>
&gt;<br>
&gt; Well... you&#39;re using mandatory as a poor-man&#39;s form of resource<br>
&gt; monitoring.<br>
&gt;<br>
&gt;&gt; But now, I would want to plug new components to spy on those flows of<br>
&gt;&gt; requests and responses, without interfering with the ongoing<br>
&gt;&gt; communications... which is not by default compatible with my use of the<br>
&gt;&gt; mandatory flag : when a &quot;spy&quot; component is monitorng request/response<br>
&gt;&gt; messages, those messages end-up in its queue, then even if the actual target<br>
&gt;&gt; component for those messages is not present on the broker (no queue), no<br>
&gt;&gt; error is returned to the sender.<br>
&gt;<br>
&gt; Indeed, which is why mandatory is probably a mis-feature and should not<br>
&gt; be used. Basically, AMQP does not really provide any sort of sane<br>
&gt; resource monitoring. We&#39;ve added in the 2.4.0 release consumer-death<br>
&gt; notifications, but that&#39;s not going to help you here. You really have a<br>
&gt; choice: make the queue non-exclusive and non-autodelete. Thus it always<br>
&gt; stays there and will always receive messages. Then, you have your<br>
&gt; clients just consume from it. The queue will do round-robining between<br>
&gt; the consumers and all should be well, but you might have reasons why you<br>
&gt; want the queue to be exclusive or autodelete. The other option is to use<br>
&gt; some other tool to do monitoring of your consumers and to address that<br>
&gt; problem outside of AMQP/RabbitMQ.<br>
&gt;<br>
&gt; Best wishes,<br>
&gt;<br>
&gt; Matthew<br>
&gt; _______________________________________________<br>
&gt; rabbitmq-discuss mailing list<br>
&gt; <a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.rabbitmq.com</a><br>
&gt; <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>