use
POSIX
qw(:sys_wait_h)
;
use
Class::Tiny
qw(name instance_id code pid parent_pid)
, {
id
=>
sub
{
my
(
$self
) =
@_
;
return
sprintf
'%s.%s'
,
$self
->name,
$self
->instance_id;
}
};
sub
BUILD {
my
(
$self
) =
@_
;
foreach
my
$req
(
qw/name instance_id code/
) {
die
"$req attribute required"
if
!
defined
$self
->
$req
;
}
if
(
ref
$self
->code ne
'CODE'
) {
die
'code attribute must be CodeRef'
;
}
$self
->parent_pid($$);
}
sub
start {
my
(
$self
) =
@_
;
$self
->pid(
$self
->_pid_check(
$self
->code->(
$self
)));
print
"# Start "
.
$self
->id .
" and run with pid: "
.
$self
->pid .
"\n"
if
$ENV
{C_P_DEBUG};
return
$self
;
}
sub
_pid_check {
my
(
$self
,
$pid
) =
@_
;
if
(!
defined
$pid
) {
die
'Undefined PID'
;
}
if
(
$pid
!~ /^(?:-)?\d+$/) {
die
"Returned PID ($pid) "
.
$self
->name .
" isn't number!"
;
}
return
$pid
;
}
sub
is_alive {
my
(
$self
) =
@_
;
return
defined
$self
->pid && !
waitpid
$self
->pid, WNOHANG;
}
sub
DESTROY {
my
(
$self
) =
@_
;
if
(
defined
$self
->parent_pid &&
$self
->parent_pid == $$ &&
$self
->pid &&
$self
->pid > 0) {
print
"# Kill PID "
.
$self
->pid.
"\n"
if
$ENV
{C_P_DEBUG};
kill
15,
$self
->pid;
}
}
1;