#!/usr/bin/perl -w

use strict;
use POE;

select STDOUT;
$| = 1;

sub increment_counter {
  my $heap = shift;
  ++$heap->{count};
}

sub spawn_another_session {
  POE::Session->create
    ( inline_states =>
      { _start => sub {
          my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];

          # Schedule a 'count' event for later.  $kernel->delay()
          # returns right away.

          $kernel->delay( count => rand($session->ID) );

          # Return to POE::Kernel, which includes the scheduler loop.
          # POE is single-threaded because Perl's threads are not
          # robust, so event handlers must return.  Otherwise the
          # Kernel will not have the opportunity to dispatch more
          # events, and the entire program will pause.
        },

        # Receive and handle a 'count' event.

        count => sub {
          my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
          print( 'session ', $session->ID,
                 ' counted to ', increment_counter($heap),
                 "\n"
               );

          # Again, schedule a delay for some time hence and return so
          # that the Kernel can continue dispatching.

          $kernel->delay( count => rand($session->ID) );
        },
      }
    );
}

# Spawn a number of threads.  It's possible to spawn hundreds of
# these, as long as you have the memory for it.

for (1..5) {
  spawn_another_session();
}

$poe_kernel->run();

