<div>Hi,</div>
<div> </div>
<div>I like the Consumer pattern, but I wanted a timed version of it. FYI: the Consumer pattern is basically a message enumerator/iterator that you can use in a foreach statement. i.e. when a message turns up, you get another pass through the loop during which your code can decide what to do with the message. Consumer lives in the <font size="2" face="Consolas"><font size="2" face="Consolas">RabbitMQ.Client.MessagePatterns namespace.</font></font></div>
<div> </div>
<div>For me, Foreach is neat approach as It hides uneccessesary detail.</div>
<div> </div>
<div>
<div>I finally managed to dig into some of the RabbitMQ source code. Is source code better than documentation? Maybe. </div></div>
<div> </div>
<div>Anyway, the functionality I wanted was always there. How did I miss that? There's a version of the Next function that has a parameter for a timed wait.</div>
<div> </div>
<div>So, instead of:</div>
<div><font size="2" face="Consolas"><font size="2" face="Consolas">
<p></p></font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">using<font size="2" face="Consolas"><font color="#000000" size="2" face="Consolas">(</font></font><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas">Subscription</font></font></font><font size="2" face="Consolas"><font color="#000000" size="2" face="Consolas"> sub=</font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">new</font></font></font><font size="2" face="Consolas"><font color="#000000" size="2" face="Consolas"> </font></font><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas">Subscription</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"><font color="#000000">(ch,QueueNme)) {</font></font></font><br>
foreach</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas">(</font></font><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas">BasicDeliverEventArgs</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> ev </font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">in</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> sub) {<br>
DoRQMessage(ev.Body);<br></font></font><font color="#008000" size="2" face="Consolas"><font color="#008000" size="2" face="Consolas"><font color="#008000" size="2" face="Consolas"> // do work here<br></font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> ch.BasicAck(ev.DeliveryTag,</font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">true</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas">);<br>
}<br> sub.Ack();<br>}</font></font>
<p>Use this instead...</p></div>
<div><font size="2" face="Consolas"><font size="2" face="Consolas">
<p></p></font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">using</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas">(</font></font><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas">Subscription</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> sub=</font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">new</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> </font></font><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas">Subscription</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas">(ch,QueueNme)) {<br>
</font></font><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas"> BasicDeliverEventArgs</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> message;<br>
</font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"> while</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas">(</font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">true</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas">) {<br>
sub.Next(5000,</font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">out</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> message); // wait up to 5 seconds<br>
</font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">if</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas">(message==</font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">null</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas">) {<br>
// logic to deal with the timeout <br></font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"> break; // kill the loop if that's what you want</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"><br>
}<br></font></font><font color="#008000" size="2" face="Consolas"><font color="#008000" size="2" face="Consolas"><font color="#008000" size="2" face="Consolas"> // do work here<br></font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> ch.BasicAck(message.DeliveryTag,</font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">true</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas">);<br>
</font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> }<br>}</font></font>
<p><font size="2" face="Consolas"><font size="2" face="Consolas">Note: behind the scenes foreach uses <font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas">IEnumerator</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas">.MoveNext(), which being parameterless, in turn calls the Next() function, not the timed version above "sub.Next(5000,<font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">out</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> message); "</font></font>. There's nothing stopping us putting in a simple if branch that accessess module level variables set by a constructor for a slightly neater approach.</font></font></font></font></p>
<p>So what is the policy on updating the Mercurial repository? If I get a spare chance, and this is desirable, I'll alter Subscribe with an additional constructor that has a timer argument. Then those of us that care can continue to use the foreach statement.</p>
</div>
<div>e.g. <font face="Consolas"><font color="#0000ff">using</font><font size="2"><font size="2">(</font></font><font color="#2b91af" size="2"><font color="#2b91af" size="2"><font color="#2b91af" size="2">Subscription</font></font></font><font size="2"><font size="2"> sub=</font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font></font><font size="2"><font size="2"> </font></font><font color="#2b91af" size="2"><font color="#2b91af" size="2"><font color="#2b91af" size="2">Subscription</font></font></font><font size="2"><font size="2">(ch,QueueNme,5000)) ... foreach(<font color="#2b91af">BasicDeliverEventArgs</font><font size="2" face="Consolas"><font size="2" face="Consolas"> ev </font></font><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas"><font color="#0000ff" size="2" face="Consolas">in</font></font></font><font size="2" face="Consolas"><font size="2" face="Consolas"> sub)</font></font></font></font></font></div>
<div> </div>
<div>Does anyone like this change? There's not a big difference between doing a foreach and a while. Just a tiny bit neater IMO.</div>
<div> </div>
<div>cheers,</div>
<div>-Steven</div>
<div> </div>
<div> </div>
<div> </div>
<div> </div>
<div> </div>
<div> </div>
<div> </div>