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/

Reply via email to