Async - Asynchronous evaluation of Perl code (with optional timeouts)
my $proc = Async->new(sub { any perl code you want executed }); if ($proc->ready) { # the code has finished executing if ($proc->error) { # something went wrong } else { $result = $proc->result; # The return value of the code } }
# or: $result = $proc->result('force completion'); # wait for it to finish
Async
executes some code in a separate process and retrieves the result. Since
the code is running in a separate process, your main program can continue
with whatever it was doing while the separate code is executing. This
separate code is called an `asynchronous computation'. When your program
wants to check to see if the asynchronous computation is complete, it can
call the ready()
method, which returns true if so, and false if it is still running.
After the asynchronous computation is complete, you should call the
error()
method to make sure that everything went all right.
error()
will return undef
if the computation completed normally, and an error message otherwise.
Data returned by the computation can be retrieved with the result()
method. The data must be a single string; any non-string value returned by
the computation will be stringized. (See AsyncData below for how to avoid
this.) If the computation has not completed yet,
result()
will return an undefined value.
result()
takes an optional parameter, $force
. If $force
is true, then the calling process will wait until the asynchronous
computation is complete before returning.
AsyncTimeout
use Async; $proc = AsyncTimeout->new(sub {...}, $timeout, $special);
Async::Timeout
implements a version of Async
that has an automatic timeout. If the asynchronous computation does not
complete before $timeout
seconds have elapsed, it is forcibly terminated and returns a special value $special
. The default special value is the string ``Timed out\n''.
All the other methods for AsyncTimeout
are exactly the same as for
Async
.
AsyncData
use Async; $proc = AsyncData->new(sub {...});
AsyncData
is just like Async
except that instead of returning a string, the asynchronous computation may
return any scalar value. If the scalar value is a reference, the result()
method will yield a refernce to a copy of this data structure.
The AsyncData
module requires that Storable
be installed.
AsyncData::new
will die if Storable
is unavailable.
All the other methods for AsyncData
are exactly the same as for
Async
.
The asynchronous computation takes place in a separate process, so nothing
it does can affect the main program. For example, if it modifies global
variables, changes the current directory, opens and closes filehandles, or
calls die
, the parent process will be unaware of these things. However, the
asynchronous computatin does inherit the main program's file handles, so if
it reads data from files that the main program had open, that data will not
be availble to the main program; similarly the asynchronous computation can
write data to the same file as the main program if it inherits an open
filehandle for that file.
The errors that are reported by the error()
mechanism are: those that are internal to Async
itself:
Couldn't make pipe: (reason) Couldn't fork: (reason) Read error: (reason)
If your asynchronous computation dies for any reason, that is not
considered to be an `error'; that is the normal termination of the process.
Any messages written to STDERR
will go to the computation's STDERR
, which is normally inherited from the main program, and the result()
will be the empty string.
use Async; sub long_running_computation { # This function simulates a computation that takes a long time to run my ($x) = @_; sleep 5; return $x+2; # Eureka! }
# Main program: my $proc = Async->new(sub {long_running_computation(2)}) or die; # The long-running computation is now executing. #
while (1) { print "Main program: The time is now ", scalar(localtime), "\n"; my $e; if ($proc->ready) { if ($e = $proc->error) { print "Something went wrong. The error was: $e\n"; } else { print "The result of the computation is: ", $proc->result, "\n"; } undef $proc; } # The result is not ready; we can go off and do something else here. sleep 1; # One thing we could do is to take nap. }
Mark-Jason Dominus mjd-perl-async+@plover.com
.