File Coverage

lib/AnyEvent/Worker/Pool.pm
Criterion Covered Total %
statement 6 36 16.6
branch 0 6 0.0
condition n/a
subroutine 2 7 28.5
pod 0 4 0.0
total 8 53 15.0


line stmt bran cond sub pod time code
1             package AnyEvent::Worker::Pool;
2              
3 1     1   4257 use common::sense 2;m{
  1         32  
  1         8  
4             use warnings;
5             use strict;
6             }x;
7              
8             #our $VERSION = '0.06';
9 1     1   70 use AnyEvent::Worker;
  1         2  
  1         611  
10              
11             =head1 NAME
12              
13             AnyEvent::Worker::Pool - Easily create a pool of workers and use'em like a single worker
14              
15             =head1 SYNOPSIS
16              
17             use AnyEvent 5;
18             use AnyEvent::Worker::Pool;
19            
20             # Create a pool of 2 workers
21             my $workers = AnyEvent::Worker::Pool->new( 2, @common_worker_init_args );
22              
23             # Will be run instantly (left 1 idle worker)
24             $workers->do( @common_worker_do_args );
25            
26             # Will be run instantly (left 0 idle workers)
27             $workers->do( @common_worker_do_args );
28            
29             # Will be run after one of busy worker will get free
30             $workers->do( @common_worker_do_args );
31              
32             $workers->take_worker(sub {
33             my $worker = shift;
34             $worker->do(@args, sub {
35             $workers>ret_worker($worker);
36             });
37             });
38            
39             =cut
40              
41             sub new {
42 0     0 0   my $pkg = shift;
43 0           my $count = shift;
44 0           my $self = bless {}, $pkg;
45 0           $self->{pool} = [
46 0           map { AnyEvent::Worker->new(@_) } 1..$count
47             ];
48 0           return $self;
49             }
50              
51             sub do {
52 0     0 0   my $self = shift;
53 0           my $cb = pop;
54 0           my @args = @_;
55             $self->take_worker(sub {
56 0     0     my $worker = shift;
57             $worker->do(@args, sub {
58 0           $self->ret_worker($worker);
59 0           goto &$cb;
60 0           });
61 0           });
62 0           return;
63             }
64              
65             sub take_worker {
66 0     0 0   my $self = shift;
67 0 0         my $cb = shift or die "cb required for take_worker at @{[(caller)[1,2]]}\n";
  0            
68             #warn("take wrk, left ".$#{$self->{pool}}." for @{[(caller)[1,2]]}\n");
69 0 0         if (@{$self->{pool}}) {
  0            
70 0           $cb->(shift @{$self->{pool}});
  0            
71             } else {
72             #warn("no worker for @{[(caller 1)[1,2]]}, maybe increase pool?");
73 0           push @{$self->{waiting_db}},$cb
  0            
74             }
75             }
76              
77             sub ret_worker {
78 0     0 0   my $self = shift;
79             #warn("ret wrk, got ".@{$self->{pool}}.'+'.@_." for @{[(caller)[1,2]]}\n");
80 0           push @{ $self->{pool} }, @_;
  0            
81 0 0         $self->take_worker(shift @{ $self->{waiting_db} }) if @{ $self->{waiting_db} };
  0            
  0            
82             }
83              
84             =head1 AUTHOR
85              
86             Mons Anderson, C<< >>
87              
88             =head1 COPYRIGHT & LICENSE
89              
90             Copyright 2009 Mons Anderson.
91              
92             This program is free software; you can redistribute it and/or modify it
93             under the same terms as Perl itself.
94              
95             =cut
96              
97             1; # End of AnyEvent::Worker::Pool