Hi Steve,<div><br></div><div>Many thanks for your prompt response. I have two proposals about improving it, while keeping all parties happy. Here they are:</div><div><br></div><div>1. Add a boolean property &quot;daemonBackgroundThreads&quot; in ConnectionFactory. Based on that property the threads created by client library would be either daemon or not. The default would be false, what wouldn&#39;t occur any changes in behavior of existing applications.</div>
<div><br></div><div>2. Alternatively the library could be rafactored that way that connection/publishing stuff be daemon threads, while listener stuff are non daemon. But as I explain further it is not best solution.</div>
<div><br></div><div>I see this problem in a bit other way, from perspective of developer, who not always can design clean solutions. Sometimes I have to wire and patch legacy systems ;). I think it is very common task to rabbitMQ users, who have to wire it into existing ecosystem. My case here is to allow some proprietary web server to send some messages during request processing. So basically I&#39;m restricted to expose a single Java method to be called from the web script. I can create my own threads, connections, bookkeeping, connection failover, reconnect etc... but this all is hidden from the interface (single method &quot;post&quot;) exposed to web scripting. The most ugly thing is that I have no other way of detecting that WebServer is going to die than adding shutdown hook to VM. And shutdown hook is fired, when all normal threads are about to die (along with daemon threads). This scenario is probably quite common for live integration of RabbitMQ into existing systems.</div>
<div><br></div><div>In general when dealing with messages we can have 3 basic scenarios:</div><div>1. Publisher.</div><div>2. Synchronous consumer.</div><div>3. Asynchronous consumer (listener on messages).</div><div><br>
</div><div>The idea of writing RabbitMQ clients (implied by costly and limited TCP/IP sockets) is to share a connection &quot;per application&quot; and write code that can reconnect in case of RabbitMQ node fail. So as soon as I get the connection, I keep it globally (shared). Usually it is my responsibility to clean on shutdown, but there are cases when I&#39;m unable to do this. The shutdown hooks are handy in those scenarios.</div>
<div><br></div><div>Only the 3rd scenario (asynchronous consumer) may require non daemon threads. But it is from my experience not a live scenario. You usually do not write application, relaying on created behind the scene &quot;main loop&quot;. Why? Because even if all what you do is to listen to messages, you still have to control the application state. You must start and stop that application as well as allow user/OS to close it. I personally for such micro-applications use Apache Daemons and run them as Windows services. On Linux you have jsvc to control such application. Surely &quot;main loop&quot; hidden in implementation is bad idea.</div>
<br><div class="gmail_quote">On Wed, May 23, 2012 at 5:18 PM, Steve Powell <span dir="ltr">&lt;<a href="mailto:steve@rabbitmq.com" target="_blank">steve@rabbitmq.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Bartłomiej,<br>
<br>
What a very good point. It is clear that the MainLoop thread ought to be<br>
a daemon thread in your circumstances, thank you for pointing this out.<br>
The only affect of this will be to allow the JVM to terminate if only<br>
daemon threads are available.<br>
<br>
However, we have considered this problem before (internal bug 21110) and<br>
user apps that create a connection and register some consumers (which do<br>
all the work) ought to be able to terminate without accidentally killing<br>
the connection processing.<br>
<br>
This means that there are circumstances in which the threads we create<br>
are required to be non-daemon, and circumstances where you would like<br>
them to be daemon.<br>
<br>
The hook you implemented ought to work correctly even when the MainLoop<br>
is not a daemon, because closing the connection ought to make the<br>
MainLoop thread terminate normally. If it doesn&#39;t, there is a bug. Where<br>
at all possible you should attempt to close an open connection as a part<br>
of your termination processing as there are system resources that could<br>
be left high-and-dry if you do not.<br>
<br>
There are other threads in the Java Client -- the executor worker<br>
threads used for Consumer callbacks. These are non-daemon, too. The hook<br>
should still work because shutting down the connection ought to shutdown<br>
the consumer work service, and in turn the executor (and its worker<br>
threads).<br>
<br>
However, I could make them daemon threads as well, in case the main app<br>
terminates abruptly and expects to be able to terminate uncleanly as you<br>
describe.<br>
<br>
Thank you for reporting this. I&#39;ll report back here on progress.<br>
<br>
Steve Powell  (a happy bunny)<br>
----------yet more definitions from the SPD----------<br>
corrugate (n.) T.V. soap scandal.<br>
olympic (n.) A camp road-digger.<br>
jamboree (n.) A conserve made from French cheese.<br>
<div><div class="h5"><br>
On 18 May 2012, at 16:27, Bartłomiej Prokop wrote:<br>
<br>
&gt; Hi,<br>
&gt;<br>
&gt; I&#39;m using JAVA client for RabbitMQ (com.rabbitmq:amqp-client:2.8.1) to write a &quot;jar component&quot; capable of sending messages for some legacy system. The idea is to wrap all code that maintain the connection inside my component. This way, the client software deals only with very simple methods like &quot;post&quot; and is not aware of any connection handling. The connect/reconnect code is written and hidden from the legacy system.<br>

&gt;<br>
&gt; The problem I have faced is that Java client creates &quot;behind the scene&quot; some threads to manage connection - like:<br>
&gt;          lines 299-301 of AMQConnection class.<br>
&gt;         // start the main loop going<br>
&gt;         new MainLoop(&quot;AMQP Connection &quot; + getHostAddress() + &quot;:&quot; + getPort()).start();<br>
&gt;         // after this point clear-up of MainLoop is triggered by closing the frameHandler.<br>
&gt;<br>
&gt; Unfortunatelly, those threads aren&#39;t &quot;daemon&quot; threads. So, when main application ends and appropriate connection closing not occurs, the VM won&#39;t terminate. My approach was to add some shutdown hook to close RabbitMQ connections if it is live inside my &quot;jar component&quot;. But, due to those non-daemon threads, VM is not going ever to be terminated and shutdown hooks fired.<br>

&gt;<br>
&gt; It is a question to RabbitMQ driver developers, if the internal threads could be fired as daemon threads, could it be done in future releases?<br>
&gt;<br>
</div></div>&gt; _______________________________________________<br>
&gt; rabbitmq-discuss mailing list<br>
&gt; <a href="mailto:rabbitmq-discuss@lists.rabbitmq.com">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>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>Bart Prokop<br>tel. +48 509 258 502<br><br>This e-mail is intended solely for the addressee(s) and contains confidential information. Unauthorized distribution, modification or disclosure of its contents is unlawful. If you have received this e-mail in error, please notify the sender immediately by return e-mail. Please then delete the e-mail from your system and do not copy it or disclose its contents to any person. Email transmission cannot be guaranteed to be secure or error free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message which arise as a result of email transmission. Information, opinions or conclusions contained in this message that do not relate to the official business of the senders employer or principal will be understood as neither given nor endorsed by it.<br>