Skip Menu |

This queue is for tickets about the IO-Async CPAN distribution.

Report information
The Basics
Id: 104127
Status: resolved
Priority: 0/
Queue: IO-Async

People
Owner: Nobody in particular
Requestors: DAKKAR [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: 0.68



Subject: IaFunction could use a post_fork / init_code callback
IaFunction could accept a callback to be invoked just after forking, before it starts waiting on the input channel. The simplest use case for this would be to set $0 to something descriptive of what the process is for. Of course setting $0 does not play well with model=>'thread'… but I think that's the caller's problem.
On Thu Apr 30 11:35:09 2015, DAKKAR wrote: Show quoted text
> IaFunction could accept a callback to be invoked just after forking, > before it starts waiting on the input channel. The simplest use case > for this would be to set $0 to something descriptive of what the > process is for.
Attached. Show quoted text
> Of course setting $0 does not play well with model=>'thread'… but I > think that's the caller's problem.
That could be done as an extension task perhaps; set $0 by default in workers. -- Paul Evans
Subject: rt104127.patch
=== modified file 'lib/IO/Async/Function.pm' --- lib/IO/Async/Function.pm 2015-07-30 15:23:37 +0000 +++ lib/IO/Async/Function.pm 2015-07-31 18:31:49 +0000 @@ -105,6 +105,16 @@ The body of the function to execute. + @result = $code->( @args ) + +=head2 init_code => CODE + +Optional. If defined, this is invoked exactly once in every child process or +thread, after it is created, but before the first invocation of the function +body itself. + + $init_code->() + =head2 model => "fork" | "thread" Optional. Requests a specific C<IO::Async::Routine> model. If not supplied, @@ -213,7 +223,7 @@ my $need_restart; - foreach (qw( code setup )) { + foreach (qw( init_code code setup )) { $need_restart++, $self->{$_} = delete $params{$_} if exists $params{$_}; } @@ -477,7 +487,7 @@ my $self = shift; my $worker = IO::Async::Function::Worker->new( - ( map { $_ => $self->{$_} } qw( model code setup exit_on_die ) ), + ( map { $_ => $self->{$_} } qw( model init_code code setup exit_on_die ) ), max_calls => $self->{max_worker_calls}, on_finish => $self->_capture_weakself( sub { @@ -560,8 +570,11 @@ my $arg_channel = IO::Async::Channel->new; my $ret_channel = IO::Async::Channel->new; + my $init = delete $params{init_code}; my $code = delete $params{code}; $params{code} = sub { + $init->() if defined $init; + while( my $args = $arg_channel->recv ) { my @ret; my $ok = eval { @ret = $code->( @$args ); 1 }; === modified file 't/42function.t' --- t/42function.t 2015-07-29 18:07:29 +0000 +++ t/42function.t 2015-07-31 18:31:49 +0000 @@ -313,6 +313,27 @@ $loop->remove( $function ); } +# init_code +{ + my $captured; + my $function = IO::Async::Function->new( + init_code => sub { $captured = 10 }, + code => sub { return $captured }, + ); + + $loop->add( $function ); + + my $f = $function->call( + args => [], + ); + + wait_for { $f->is_ready }; + + is( scalar $f->get, 10, 'init_code can side-effect captured variables' ); + + $loop->remove( $function ); +} + ## Now test that parallel runs really are parallel { # touch $dir/$n in each worker, touch $dir/done to finish it
Released -- Paul Evans