On Thu, Dec 30, 2004 at 08:53:56PM +0100, Bas A. Schulte wrote:
> Hi,
>
> when I have one session delayed like so:
>
> ...
>
> my $wait = 5;
>
> $kernel->delay(post_query => $wait);
>
> ...
>
>
> And I want to short-cut that delay (i.e. continue to event "post_query"
> now instead of waiting until the 5 seconds are done) from another
> session, how can I do that? I do have the delayed session's alias, but
> how do I signal that session to go on?
POE doesn't have a built-in way to short-circuit a delay. That's not
to say it's impossible. Here's a generic, possibly over-simplified
way:
sub post_query_later {
my ($kernel, $heap, $wait) = @_[KERNEL, HEAP, ARG0];
$kernel->delay(post_query => $wait);
$heap->{waiting_to_post_query} = 1;
}
sub post_query_now {
my ($kernel, $heap) = @_[KERNEL, ARG0];
# Don't expedite it if we're not waiting anymore.
return unless delete $heap->{waiting_to_post_query};
# Cancel the delay.
$kernel->delay(post_query => undef);
# Expedite the event.
$kernel->yield("post_query");
}
Then one session would tell the other to stop waiting:
$kernel->post(alias => "post_query_now");
If you plan to do a lot of this, it may be productive to abstract it
all into a small library.
package ExpeditedTimers;
use POE::Kernel; # exports $poe_kernel
sub do_later {
my ($class, $event, $wait) = @_;
my $heap = $poe_kernel->get_active_session()->get_heap();
$poe_kernel->delay($event, $wait);
$heap->{"pending_$event"} = 1;
}
sub expedite {
my ($class, $event) = @_;
my $heap = $poe_kernel->get_active_session()->get_heap();
return unless delete $heap->{"pending_$event"};
$poe_kernel->delay($event, undef);
$poe_kernel->yield($event);
}
1;
It's still meant to be called from the session that will be doing
things.
ExpeditedTimer->do_later("post_query", 5);
ExpeditedTimer->expedite("post_query");
(It's also not tested code, so your mileage may vary.)
--
Rocco Caputo - http://poe.perl.org/