People are used to doing some work, pausing a bit, and doing some more work:
sub task { print "Doing some work...\n"; # Wait a little bit. sleep(5); print "Doing some more work...\n"; }
This is fine when a program only has one task. It's even perfectly acceptable in singletasking POE programs.
Unfortunately that sleep() call is going to pause the whole shebang in a program that's trying to multitask. The most direct way to avoid that is to break a task into parts.
# beforehand $kernel->state('event_part_two', \&task_part_two); sub task_part_one { # Do some work. ...; # Ask POE::Kernel to give this session an "event_part_two" # event after five seconds have passed. $kernel->delay(event_part_two => 5); } sub task_part_two { # Do some more work. ...; }
Each event is tied to some code, so receiving "event_part_two" is the same as calling &task_part_two. Unlike with sleep(), though, POE::Kernel is free to do other things in the meantime.
Here's a complete working example:
#!/usr/bin/perl use warnings; use strict; use POE; $| = 1; POE::Session->create( inline_states => { _start => \&bootstrap, event_part_one => \&task_part_one, event_part_two => \&task_part_two, something_else => \&do_something_else, } ); POE::Kernel->run(); exit; sub bootstrap { $_[HEAP]->{is_running} = 1; $_[KERNEL]->yield("event_part_one"); $_[KERNEL]->yield("something_else"); } sub task_part_one { print "Doing some work here...\n"; $_[KERNEL]->delay(event_part_two => 1); } sub task_part_two { print "\nFinishing up now.\n"; $_[HEAP]->{is_running} = 0; } sub do_something_else { print "."; $_[KERNEL]->yield("something_else") if $_[HEAP]->{is_running}; }
See also: /Looping