Async-Group
view release on metacpan or search on metacpan
############################################################
#
# $Header: /mnt/barrayar/d06/home/domi/Tools/perlDev/Async_Group/RCS/Group.pm,v 1.2 1998/11/20 12:31:02 domi Exp $
#
# $Source: /mnt/barrayar/d06/home/domi/Tools/perlDev/Async_Group/RCS/Group.pm,v $
# $Revision: 1.2 $
# $Locker: $
#
############################################################
package Async::Group ;
use Carp ;
#use AutoLoader 'AUTOLOAD' ;
use strict ;
use vars qw($VERSION) ;
$VERSION = substr q$Revision: 1.2 $, 10;
# see loadspecs for other names
sub new
{
my $type = shift ;
my $self = {} ;
my %args = @_ ;
$self->{name}='' ;
foreach (qw/name test/)
{
$self->{$_}= $args{$_} ;
}
bless $self,$type ;
}
sub getCbRef
{
my $self = shift;
return sub{$self->callDone(@_)} ;
}
sub printEvent
{
my $self = shift ;
warn "$self->{name} ",shift if $self->{test} ;
}
# Call a set of asynchronous functions which MUST have their set of user
# callbacks.. Note that the user call-back invoked when the function MUST
# call the asyncDone function with a result.
#
# When all function calls are over (i.e. all call-back were performed)
# all the returned results are logically 'anded' and the resulting result
# is passed to the main user call-back function
sub run
{
my $self = shift ;
# 'set' => [ sub { } ,... ]
# 'callback' => 'method_name'
my %args = @_ ;
foreach (qw/set callback/)
{
croak( "No $_ passed to Async::Group::run\n") unless
defined $args{$_};
}
croak( "$self->name:Async::Group: set parameter is not an array ref\n")
unless ref($args{set}) eq 'ARRAY' ;
# initialize
$self->{result} = 1 ;
$self->{out} = '' ;
# compute nb of asynchronous calls that will be done
$self->{onGoing} = scalar (@{$args{set}}) ;
# make up some log message
$self->printEvent("asynCall called for ".
$self->{onGoing}." calls");
# store what to do when the asyncGroup is all done
$self->{callback} = $args{'callback'} ;
# call them
foreach my $func ( @{$args{set}} )
{
&$func ;
}
}
# expects asyncGroup id and a result as parameter
sub callDone
{
my $self= shift ;
my $result = shift ;
my $str = shift ;
# no more info can be passed back, since we don't know what to do with
# the results until all applied function are finished
#store results
$self->{out} .= $str if defined $str ;
$self->{result} &&= $result ;
$self->printEvent("Async::Group call done ($result), ".
-- $self->{onGoing}
." left to do\n");
unless ($self->{onGoing})
{
$self->printEvent
("Async::Group finished, global result is $self->{result}\n"
.$self->{out}) ;
my $cb = $self->{'callback'} ;
&$cb($self->{result},$self->{out});
}
}
1;
__END__
=head1 NAME
Async::Group - Perl class to deal with simultaneous asynchronous calls
=head1 SYNOPSIS
use Async::Group ;
use strict ;
sub sub1
{
print "Dummy subroutine \n";
my $dummy = shift ;
my $cb = shift ;
&$cb(1);
}
sub allDone
{
print "All done, result is ", shift ,"\n" ;
}
my $a = Async::Group->new(name => 'aTest', test => 1) ;
$a->run(set => [ sub {&sub1( callback => sub {$a->callDone(@_)} )},
sub {&sub1( callback => sub {$a->callDone(@_)} )} ],
callback => \&allDone
)
# or another way which avoids the clumsy nested subs
my $cb = $a->getCbRef();
$a->run(set => [ sub {&sub1( callback => $cb)},
sub {&nsub1( callback => $cb )} ],
callback => \&allDone
)
=head1 DESCRIPTION
If you sometimes have to launch several asynchronous calls in
parrallel and want to call one call-back function when all these calls
are finished, this module may be for you.
Async::Group is a class which enables you to call several asynchronous
routines. Each routine may have their own callback. When all the
routine are over (i.e. all their callback were called), Async::Group
will call the global callback given by the user.
Note that one Async::Group objects must be created for each group of
parrallel calls. This object may be destroyed (or will vanish itself)
once the global callback is called.
Note also that Async::Group does not perform any fork or other system
calls. It just run the passed subroutines and keep count of the
call-back functions called by the aforementionned subroutines. When
all these subs are finished, it calls another call-back (passed by the
user) to perform whatever function required by the user.
Using fork or threads or whatever is left to the user.
=head1 Methods
=head2 new( set => [sub, sub, ...], [test => 1] )
Creates a new Async::Group object.
parameters are :
- name: name of the group. The name has no special meaning but it can be
helpfull for debugging.
- test: will print on STDERR what's going on
=head2 run ('set' => [ sub { } ,... ], 'callback' => sub{ ...} )
- set: array ref of a set of subroutine reference that will be called in
parrallel
- callback : global user callback function
=head2 callDone(result, [string])
Function to be called back each time an asynchronous call is finished.
When all function calls are over (i.e. all call-back were performed)
all the returned results are logically 'anded', the passed strings are
concatenated and the resulting result is passed to the global user
call-back function passed with the run() method.
=head2 getCbRef()
Syntactic sugar to avoid nested subs when defining the set of routines
that must be run in parrallel. This function will return a sub ref
that can be used as a callback function by the user's routine.
So you may call run() with the following sequence :
my $cb = $a->getCbRef();
$a->run(set => [ sub {&sub1( callback => $cb)},
sub {&nsub1( callback => $cb )} ],
callback => \&allDone
)
=head1 AUTHOR
Dominique Dumont, Dominique_Dumont@grenoble.hp.com
Copyright (c) 1998 Dominique Dumont. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=head1 SEE ALSO
perl(1)
=cut
( run in 1.650 second using v1.01-cache-2.11-cpan-39bf76dae61 )