App-Context
view release on metacpan or search on metacpan
lib/App/Context/Server.pm view on Meta::CPAN
if ($self->{num_procs} < $self->{max_procs} &&
(!defined $self->{max_async_events} || $self->{num_async_events} < $self->{max_async_events})) {
$event->{destination} = $self->{host};
$assigned = 1;
}
&App::sub_exit($assigned) if ($App::trace);
return($assigned);
}
sub send_async_event_now {
&App::sub_entry if ($App::trace);
my ($self, $event, $callback_event) = @_;
if ($event->{destination} eq "in_process") {
my $event_token = $self->send_async_event_in_process($event, $callback_event);
}
else {
my $pid = $self->fork();
if (!$pid) { # running in child
my $exitval = 0;
my (@results);
eval {
@results = $self->send_event($event);
};
if ($@) {
@results = ($@);
}
if ($#results > -1 && defined $results[0] && $results[0] ne "") {
my $textfile = $self->{options}{prefix} . "/data/app/Context/$$";
if (open(FILE, "> $textfile")) {
print App::Context::Server::FILE @results;
close(App::Context::Server::FILE);
}
else {
$exitval = 1;
}
}
$self->shutdown();
$self->exit($exitval);
}
my $destination = $event->{destination} || "local";
$self->{num_async_events}++;
$self->{node}{$destination}{num_async_events}++;
my $runtime_event_token = $pid;
$self->{running_async_event}{$runtime_event_token} = [ $event, $callback_event ];
}
&App::sub_exit() if ($App::trace);
}
=head2 wait_for_event()
* Signature: $self->wait_for_event($event_token)
* Param: $event_token string
* Return: void
* Throws: App::Exception
* Since: 0.01
Sample Usage:
$self->wait_for_event($event_token);
The wait_for_event() method is called when an asynchronous event has been
sent and no more processing can be completed before it is done.
=cut
sub wait_for_event {
&App::sub_entry if ($App::trace);
my ($self, $event_token) = @_;
&App::sub_exit() if ($App::trace);
}
sub fork {
&App::sub_entry if ($App::trace);
my ($self) = @_;
my $pid = $self->SUPER::fork();
if ($pid) { # the parent process has a new child process
$self->{num_procs}++;
$self->{proc}{$pid} = {};
}
else { # the new child process has no sub-processes
$self->{num_procs} = 0;
$self->{proc} = {};
$SIG{INT} = sub { $self->log({level=>2},"Caught Signal: @_ (quitting)\n"); $self->exit(102); }; # SIG 2
$SIG{QUIT} = sub { $self->log({level=>2},"Caught Signal: @_ (quitting)\n"); $self->exit(103); }; # SIG 3
$SIG{TERM} = sub { $self->log({level=>2},"Caught Signal: @_ (quitting)\n"); $self->exit(115); }; # SIG 15
}
&App::sub_exit($pid) if ($App::trace);
return($pid);
}
sub finish_pid {
&App::sub_entry if ($App::trace);
my ($self, $pid, $exitval, $sig) = @_;
$self->{num_procs}--;
delete $self->{proc}{$pid};
my $runtime_event_token = $pid;
my $async_event = $self->{running_async_event}{$runtime_event_token};
if ($async_event) {
my ($event, $callback_event) = @$async_event;
my $returnval = "";
my $returnvalfile = $self->{options}{prefix} . "/data/app/Context/$pid";
if (open(FILE, $returnvalfile)) {
if ($callback_event) {
$returnval = join("",<App::Context::Server::FILE>);
}
close(App::Context::Server::FILE);
unlink($returnvalfile);
}
my $destination = $event->{destination} || "local";
$self->{num_async_events}--;
$self->{node}{$destination}{num_async_events}--;
delete $self->{running_async_event}{$runtime_event_token};
if ($callback_event) {
$callback_event->{args} = [] if (! $callback_event->{args});
my $errmsg = ($exitval || $sig) ? "Exit $exitval on $pid [sig=$sig]" : "";
push(@{$callback_event->{args}},
{event_token => $callback_event->{event_token}, returnval => $returnval, errnum => $exitval, errmsg => $errmsg});
( run in 1.726 second using v1.01-cache-2.11-cpan-437f7b0c052 )