Acme-Spork
view release on metacpan or search on metacpan
lib/Acme/Spork.pm view on Meta::CPAN
}
else {
close $CHILD_RDR;
close $PARENT_WTR;
for my $stdfh (qw(STDIN STDOUT STDERR)) {
close $stdfh;
if(exists $reopen_stdfhs_to{ $stdfh } && ref $reopen_stdfhs_to{ $stdfh } eq 'ARRAY') {
eval "open( $stdfh, " . join(', ', map { qq{"$_"} } @{ $reopen_stdfhs_to{ $stdfh } }) . ' );';
carp "Could not reopen $stdfh : $@" if $@;
# no strict 'refs';
# open( $stdfh , @{ $reopen_stdfhs_to{ $stdfh } }) or carp "Could not reopen $stdfh : $!";
}
}
## if (!defined &setsid) {
## require POSIX;
## *setsid = *POSIX::setsid;
## }
##
## setsid();
## $SIG{CHLD} = 'DEFAULT';
$spork->(@_);
CORE::exit(0);
}
}
}
sub daemonize {
require Proc::Daemon;
{
local $SIG{'HUP'} = $SIG{'HUP'} || ''; # workaround until http://rt.cpan.org/Public/Bug/Display.html?id=21453
goto &Proc::Daemon::Init;
}
}
sub daemonize_without_close_on {
require Proc::Daemon;
{
no warnings 'redefine';
local *POSIX::close = sub { return 1; }; # the "without_close_on" part
local $SIG{'HUP'} = $SIG{'HUP'} || ''; # workaround until http://rt.cpan.org/Public/Bug/Display.html?id=21453
Proc::Daemon::Init(@_);
}
}
1;
__END__
=head1 NAME
Acme::Spork - Perl extension for spork()ing in your script
=head1 SYNOPSIS
use Acme::Spork;
my $spork_pid = spork(\&long_running_code, @ARGV)
or die "Could not fork for spork: $!";
print "Long running code has been started as PID $spork_pid, bye!\n";
=head1 DESCRIPTION
A spork in the plastic sense is a fork combined with a spoon. In programming I've come to call a spork() a fork() that does more than just a fork.
I use it to describe when you want to fork() to run some long running code but immediately return to the main program instead of waiting for it.
=head1 spork()
The first argument is a code ref that gets executed and any other args are passed to the call to the code ref.
#!/usr/bin/perl
use strict;
use warnings;
use Acme::Spork;
print 1;
spork(
sub {
sleep 5;
open my $log_fh, '>>', 'spork.log', or die "spork.log open failed: $!";
print {$log_fh} "I am spork hear me spoon\n";
close $log_fh;
},
) or die qq{Couldn't fork for spork: $!};
print 2;
This prints out "12" immediately and is done running, now if you tail -f spork.log you'll see "I am spork hear me spoon\n" get written to it 4 or 5 seconds later by the spork()ed process :)
spork() returns the PID of the spork()ed process so you can keep track of them and do what you need with it.
If it returns false then fork failed so you can:
if(spork(\&foo)) {
print "I am spork here me spoon\n";
}
else {
print "Could not fork for spork: $!";
}
my $spork_pid = spork(\&foo) or die "Could not fork for for spork: $!";
=head2 %reopen_stdfhs_to
You can now have spork reopen one or more of STDIN, STDOUT, STDERR.
You define how this is handled in the Acme::Spork hash '%reopen_stdfhs_to'
The key is the STD* handle (any other values are simply ignored).
The value is an array reference of arguments to open().
Its always a good idea to local()ize it as well (and specify all 3 handles, otherwise you may get some strange warnings and behavior):
local %Acme::Spork::reopen_stdfhs_to = (
STDIN => [qw(< /dev/null)],
STDOUT => [qw(> /dev/null)],
STDERR => [qw(> &STDOUT)],
);
spork(...)
( run in 1.117 second using v1.01-cache-2.11-cpan-98e64b0badf )