This is a rough continuation of
http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2010-September/009032.html
which is the only mailing list post I could find relevant to my issue.
(Aside: kudos to Matthew Sackman for clear explanations including
ASCII diagrams!)
I have a similar application to Erik which supervises a connection via
a worker and creates a channel per application worker process so that
channel exceptions kill only worker processes and the entire
supervision tree is torn down by a connection exception. In general
this works brilliantly well. However, on rare but possible occasions,
the following happens when a worker process opens a channel:
{ok, ChanPid} = amqp_connection:open_channel(ConnPid),
% self() dies due to exit signal from another linked process
link(ChanPid), % we never get here due to exit race
Unfortunately, this leaves a "hanging chad" channel in the supervision
tree. Am I missing something subtle? Is it possible to avoid such a
race?
Best,
Hunter Morris
[rabbitmq-discuss] Linking to a channel process (erlang client)
| Tweet |
|
Search Discussions
-
Matthew Sackman at Jun 14, 2011 at 11:45 pm ⇧
Hmm, that's tricky. Depends what you want to do really - you could haveOn Tue, Jun 14, 2011 at 06:22:41PM +0100, Hunter Morris wrote:
I have a similar application to Erik which supervises a connection via
a worker and creates a channel per application worker process so that
channel exceptions kill only worker processes and the entire
supervision tree is torn down by a connection exception. In general
this works brilliantly well. However, on rare but possible occasions,
the following happens when a worker process opens a channel:
{ok, ChanPid} = amqp_connection:open_channel(ConnPid),
% self() dies due to exit signal from another linked process
link(ChanPid), % we never get here due to exit race
Unfortunately, this leaves a "hanging chad" channel in the supervision
tree. Am I missing something subtle? Is it possible to avoid such a
race?
the supervisor link to the base process that is the amqp_client
application if you want (before starting any workers), but it depends if
you want death of your application to tear down the whole client -
sequencing of those actions to achieve a safe, controlled shutdown, is
not trivial.
My understanding is that on the whole, libraries that spawn processes
are linked to, or monitored, rather than linking / monitoring their
clients. However, this may be wrong and/or not best practise. If you
have ideas how this can be improved, please do let us know.
Best wishes,
Matthew
-
Hunter Morris at Jun 15, 2011 at 12:05 pm ⇧
Currently, my application's top-level supervisor starts amqp_sup as aOn Wed, Jun 15, 2011 at 12:45 AM, Matthew Sackman wrote:
Hmm, that's tricky. Depends what you want to do really - you could have
the supervisor link to the base process that is the amqp_client
application if you want (before starting any workers), but it depends if
you want death of your application to tear down the whole client -
sequencing of those actions to achieve a safe, controlled shutdown, is
not trivial.
child itself which gives the behaviour I want when my application
crashes. That works quite well and behaves as I expect.My understanding is that on the whole, libraries that spawn processesMy main concern is leaking processes since client-side channels are
are linked to, or monitored, rather than linking / monitoring their
clients. However, this may be wrong and/or not best practise. If you
have ideas how this can be improved, please do let us know.
composed of at least 3 processes each (and I expect hundreds of
channels in this particular application).
I've seen other "client" applications which manage socket connections
treat this issue very differently. For example, lhttpc
(https://github.com/esl/lhttpc) spawn_links a simple lhttpc_client
process, passing along self() in order to unlink when a request is
finished. Obviously, HTTP clients are largely stateless which differs
greatly from the situation we have with AMQP connections and channels.
Based on a suggestion, I will most likely trap exits in the worker
process while setting up the link to the channel in order to clean up
if it receives an exit signal from elsewhere. Because the worker
processes are quite simple, this should be fine.
Thanks for your help,
Hunter
-
Matthew Sackman at Jun 15, 2011 at 12:10 pm ⇧
Interesting, and thanks for the pointer. I'll take a look at that and weOn Wed, Jun 15, 2011 at 01:05:44PM +0100, Hunter Morris wrote:
I've seen other "client" applications which manage socket connections
treat this issue very differently. For example, lhttpc
(https://github.com/esl/lhttpc) spawn_links a simple lhttpc_client
process, passing along self() in order to unlink when a request is
finished. Obviously, HTTP clients are largely stateless which differs
greatly from the situation we have with AMQP connections and channels.
may well change the behaviour here, or at least introduce a start_link
variant as there used to be.
Matthew
Related Discussions
Discussion Navigation
| view | thread | post |
Discussion Overview
| group | rabbitmq-discuss |
| categories | rabbitmq |
| posted | Jun 14, '11 at 5:22p |
| active | Jun 15, '11 at 12:10p |
| posts | 4 |
| users | 2 |
| website | rabbitmq.com |
| irc | #rabbitmq |
