# Simple worker pool component.
# Simulates a long-running, asynchronous task.
# Copyright 2004 by Rocco Caputo.  Free software.
# Same terms as Perl itself.  Have fun!

package WorkerPool;

use warnings;
use strict;

use POE;

sub spawn {
  my ($class, %args) = @_;
  POE::Session->create(
    inline_states => {
      _start     => \&handle_start,
      _child     => \&handle_child,
      spawn_more => \&do_spawn_more,
    },
    heap => \%args,
  );
}

sub handle_start {
  $_[HEAP]->{running} = 0;
  &spawn_more;
}

sub handle_child {
  return unless $_[ARG0] eq "lose";
  $_[HEAP]->{running}--;
  &spawn_more;
}

sub spawn_more {
  my $heap = $_[HEAP];

  while (
    $heap->{running} < $heap->{max_parallel}
  ) {
    my $next_job = $heap->{job_fetcher}->();
    return unless defined $next_job;
    my %job_spec = %$next_job;
    $job_spec{worker_class}->spawn(%job_spec);
    $heap->{running}++;
  }
}

1;
