Skip Menu |

This queue is for tickets about the Net--RabbitMQ CPAN distribution.

Report information
The Basics
Id: 70973
Status: open
Priority: 0/
Queue: Net--RabbitMQ

People
Owner: Nobody in particular
Requestors: mutant.nz [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.2.2
Fixed in: (no value)



Subject: Problems with losing connection when forking
It seems this module suffers from loss of connection when a process opens a connection, forks and the child exits. This is due to the DESTROY method getting called on the connection when the child process exits, even when the parent process still has a reference to the connection handle. Minimal(ish) example: my $mq = Net::RabbitMQ->new(); $mq->connect("localhost", { user => "guest", password => "guest" }); $mq->channel_open(1); my $queue = $mq->queue_declare(1, '', { exclusive => 1 }); $mq->consume(1, $queue, {}); my $pid = fork(); die "Couldn't fork\n" unless defined $pid; if (! $pid) { # Child exit; } $mq->recv(); The call to recv() dies with "Bad frame read.", because the connection has been destroyed when the child exits. This is a problem when writing a daemon that blocks waiting for a message, then forks to process it. I would suggest adding something equivalent to DBI's "InvactiveDestroy" parameter (which is solving the same problem), so that a handle can be prevented from disconnecting when getting destroyed. I may have time to patch this at a later date, although any help/suggestions would be appreciated (I have minimal XS skills).
On 2011-09-14 18:05:24, Mutant wrote: Show quoted text
> It seems this module suffers from loss of connection when a process > opens a connection, forks and the child exits. This is due to the > DESTROY method getting called on the connection when the child process > exits, even when the parent process still has a reference to the > connection handle. Minimal(ish) example: > > my $mq = Net::RabbitMQ->new(); > $mq->connect("localhost", { user => "guest", password => "guest" }); > > $mq->channel_open(1); > my $queue = $mq->queue_declare(1, '', { exclusive => 1 }); > $mq->consume(1, $queue, {}); > > my $pid = fork(); > die "Couldn't fork\n" unless defined $pid; > > if (! $pid) { > # Child > exit; > } > > $mq->recv(); > > The call to recv() dies with "Bad frame read.", because the connection > has been destroyed when the child exits. This is a problem when writing > a daemon that blocks waiting for a message, then forks to process it. > > I would suggest adding something equivalent to DBI's "InvactiveDestroy" > parameter (which is solving the same problem), so that a handle can be > prevented from disconnecting when getting destroyed.
An even nicer method is the recently added "AutoInactiveDestroy" parameter, which automatically detects if DESTROY is called in the child. But "InactiveDestroy" is still useful if the work should be done just in the child and not in the parent. Show quoted text
> > I may have time to patch this at a later date, although any > help/suggestions would be appreciated (I have minimal XS skills).
Another workaround is to use damn() from Acme::Damn module here. Just call "damn $mq" in the child (location of the call does not matter), and the DESTROY method won't be called anymore. Regards, Slaven