use strict;
our $VERSION = '0.1.2';
use POSIX qw(:sys_wait_h);
use Class::Tiny qw(name code), { instances => 1, };
=head1 NAME
Continual::Process - (re)start dead process
=head1 SYNOPSIS
use Continual::Process;
use Continual::Process::Loop;
my $loop = Continual::Process::Loop->new(
instances => [
Continual::Process->new(
name => 'job1',
code => sub {
my $pid = fork;
if ($pid) {
return $pid;
}
say "Hello world";
sleep 5;
say "Bye, bye world";
exit 1;
},
instances => 4,
)->create_instance(),
Continual::Process->new(
name => 'job2',
code => sub {
my $pid = fork;
if ($pid) {
return $pid;
}
exec 'perl -ne "sleep 1"';
exit 1;
},
)->create_instance(),
]
);
$loop->run();
=head1 DESCRIPTION
Continual::Process with Continual::Process::Loop is a way how to run a process forever.
Continual::Process creates Continual::Process::Instance which runs in a loop and if it dies, it starts again.
The code for starting a process is OS-agnostic. The only condition is that the code must return PID of the new process.
=head2 loop
Continual::Process supports more loops:
=over 1
=item L<Continual::Process::Loop::Simple> - simple while/sleep loop
=item L<Continual::Process::Loop::AnyEvent> - L<AnyEvent> support
=item L<Continual::Process::Loop::Mojo> - L<Mojo::IOLoop> support
=back
=head1 METHODS
=head2 new(%attributes)
=head3 %attributes
=head4 name
name of process (only for identification)
=head4 code
CodeRef which start new process and returned C<PID> of new process
I<code>-sub B<must> return C<PID> of the new process or die!
for example Linux and fork:
code => sub {
if (my $pid = fork) {
return $pid;
}
...
exit 1;
}
or Windows and L<Win32::Process>
code => sub {
my ($instance) = @_;
Win32::Process::Create(
$ProcessObj,
"C:\\winnt\\system32\\notepad.exe",
"notepad temp.txt",
0,
NORMAL_PRIORITY_CLASS,
"."
) || die "Process ".$instance->name." start fail: ".$^E;
return $ProcessObj->GetProcessID();
}
best way is use L<Continual::Process::Helper> C<prepare_fork> or C<prepare_run> method
=head4 instances
count of running instances
default I<1>
=cut
sub BUILD {
my ($self) = @_;
foreach my $req (qw/name code/) {
die "$req attribute required" if !defined $self->$req;
}
if (ref $self->code ne 'CODE') {
die 'code attribute must be CodeRef';
}
}
=head2 create_instance()
create and return list of L<Continual::Process::Instance>
=cut
sub create_instance {
my ($self) = @_;
my @instances;
foreach my $instance_id (1 .. $self->instances) {
push @instances,
Continual::Process::Instance->new(
name => $self->name,
instance_id => $instance_id,
code => $self->code,
);
}
return @instances;
}
=head1 LICENSE
Copyright (C) Avast Software.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=head1 AUTHOR
Jan Seidl E<lt>seidl@avast.comE<gt>
=cut
1;