I have a library that needs to fork()
to fire-and-forget some code. However when the child process spawned by fork()
is destroyed, the DBD::Pg
's END
is called and inadvertently kills the parents connection. On-top of this, the code has no access to the $dbh
, and can't use DBI
.
Here is some code that reproduces the issue:
use strict;
use warnings;
use DBI;
my $dbh = DBI->connect('dbi:Pg:dbname=foo', '', '');
if (!fork()) {
CORE::say 'In child, doing stuff!';
exit 0;
}
sleep 2; # Provide adequate time for the child to be reaped.
my $sth = $dbh->prepare(q[select NOW();]);
$sth->execute(); # Error! Something, something, connection terminated!
my $time = $sth->fetch->[0];
CORE::say "It is $time o'clock";
Here is the error:
DBD::Pg::st execute failed: server closed the connection unexpectedly
This probably means the server terminated abnormally
Instead of using exit
, you can use POSIX::_exit
, this causes END
's to not be evaluated when the child exits.
use strict;
use warnings;
use POSIX;
use DBI;
my $dbh = DBI->connect('dbi:Pg:dbname=foo', '', '');
if (!fork()) {
CORE::say 'In child, doing stuff!';
POSIX::_exit(0);
}
sleep 2; # Provide adequate time for the child to be reaped.
my $sth = $dbh->prepare(q[select NOW();]);
$sth->execute(); # Error! Something, something, connection terminated!
my $time = $sth->fetch->[0];
CORE::say "It is $time o'clock";