AnyEvent-Task

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    in use by the client are duped into the worker process and the worker
    ought to close these extra descriptors. Also, forking a busy client may
    be memory-inefficient (and dangerous if it uses threads).

    Since it's more of a bother than it's worth to run the server and the
    client in the same process, there is an alternate server constructor,
    "AnyEvent::Task::Server::fork_task_server" for when you'd like to fork a
    dedicated server process. It can be passed the same arguments as the
    regular "new" constructor:

        ## my ($keepalive_pipe, $server_pid) =
        AnyEvent::Task::Server::fork_task_server(
          name => 'hello',
          listen => ['unix/', '/tmp/anyevent-task.socket'],
          interface => sub {
                             return "Hello from PID $$";
                           },
        );

    The only differences between this and the regular constructor is that
    "fork_task_server" will fork a process which becomes the server and will
    also install a "keep-alive" pipe between the server and the client. This
    keep-alive pipe will be used by the server to detect when its parent
    (the client process) exits.

    If "AnyEvent::Task::Server::fork_task_server" is called in a void
    context then the reference to this keep-alive pipe is pushed onto
    @AnyEvent::Task::Server::children_sockets. Otherwise, the keep-alive
    pipe and the server's PID are returned. Closing the pipe will terminate
    the server gracefully. "kill" the PID to terminate it immediately. Note
    that even when the server is shutdown, existing worker processes and
    checkouts may still be active in the client. The client object and all
    checkout objects should be destroyed if you wish to ensure all workers
    are shutdown.

    Since the "fork_task_server" constructor calls fork and requires using
    AnyEvent in both the parent and child processes, it is important that
    you not install any AnyEvent watchers before calling it. The usual

lib/AnyEvent/Task.pm  view on Meta::CPAN



=head1 STARTING THE SERVER

Typically you will want to start the client and server as completely separate processes as shown in the synopses.

Running the server and the client in the same process is technically possible but is highly discouraged since the server will C<fork()> when the client demands a new worker process. In this case, all descriptors in use by the client are duped into th...

Since it's more of a bother than it's worth to run the server and the client in the same process, there is an alternate server constructor, C<AnyEvent::Task::Server::fork_task_server> for when you'd like to fork a dedicated server process. It can be ...

    ## my ($keepalive_pipe, $server_pid) =
    AnyEvent::Task::Server::fork_task_server(
      name => 'hello',
      listen => ['unix/', '/tmp/anyevent-task.socket'],
      interface => sub {
                         return "Hello from PID $$";
                       },
    );

The only differences between this and the regular constructor is that C<fork_task_server> will fork a process which becomes the server and will also install a "keep-alive" pipe between the server and the client. This keep-alive pipe will be used by t...

If C<AnyEvent::Task::Server::fork_task_server> is called in a void context then the reference to this keep-alive pipe is pushed onto C<@AnyEvent::Task::Server::children_sockets>. Otherwise, the keep-alive pipe and the server's PID are returned. Closi...

Since the C<fork_task_server> constructor calls fork and requires using AnyEvent in both the parent and child processes, it is important that you not install any AnyEvent watchers before calling it. The usual caveats about forking AnyEvent processes ...

You should also not call C<fork_task_server> after having started threads since, again, this function calls fork. Forking a threaded process is dangerous because the threads might have userspace data-structures in inconsistent states at the time of t...





=head1 INTERFACE

lib/AnyEvent/Task/Server.pm  view on Meta::CPAN

  if ($rv) {
    close($fh);
    close($monitor_fh2);

    $self->{children}->{$rv} = {
      monitor_fh => $monitor_fh1,
    };
  } elsif ($rv == 0) {
    close($monitor_fh1);

    ## Don't want keep-alive pipes of other workers open in this worker
    foreach my $child (keys %{$self->{children}}) {
      close($self->{children}->{$child}->{monitor_fh});
    }

    if (defined $self->{name}) {
      $0 = "AET-Worker:$self->{name}($self->{curr_worker_id})";
    }

    AnyEvent::Task::Server::Worker::handle_worker($self, $fh, $monitor_fh2);
    die "handle_worker should never return";

lib/AnyEvent/Task/Util.pm  view on Meta::CPAN


    $code->();

    die "AnyEvent::Task::Server->run should never return";
  }

  close $sockb;

  return ($socka, $pid) if wantarray;

  push @children_sockets, $socka; # keep reference alive
  return;
}



1;

t/timeout-log-defer.t  view on Meta::CPAN


use AnyEvent::Util;
use AnyEvent::Task::Server;
use AnyEvent::Task::Client;

use Test::More tests => 3;


## The point of this test is to verify that if a timeout error is thrown
## from a checkout with a log_defer_object then a reference to the Log::Defer
## object is not kept alive by the cmd_handler closure of the checkout. This was
## a bug in AE::T 0.802.


AnyEvent::Task::Server::fork_task_server(
  listen => ['unix/', '/tmp/anyevent-task-test.socket'],
  interface => sub {
                     select undef, undef, undef, 0.4;
                     die "shouldn't get here";
                   },
);

t/timeout-log-defer.t  view on Meta::CPAN

my $cv = AE::cv;

{
  my $ld = Log::Defer->new(sub {
    ok($error_thrown, 'log defer obj destroyed after error handler ran');
    $cv->send;
  });

  frame_try {
    $client->checkout( timeout => 0.2, log_defer_object => $ld )->(sub {
      $ld->warn("keep alive 1");
      die "checkout was serviced?";
    });
  } frame_catch {
    $ld->warn("keep alive 2");
    my $err = $@;
    ok(1, "timeout hit");
    ok($err =~ /timed out after/, 'correct err msg');
    $error_thrown = 1;
  };
}

my $timer = AE::timer 1, 0, sub {
  fail("log defer object destroyed");
  $cv->send;



( run in 0.698 second using v1.01-cache-2.11-cpan-df04353d9ac )