Re: Creating active timers within callbacks

[email protected] (John Christian) Thu, 08 Jan 2004 15:33:23 -0800
Newsgroups perl.loop
Message-ID <[email protected]>
Do'h!  Ok ... I see my problem.  In my IO callback there's a loop around 
the socket accept, so it's just not returning to the Event::loop, and 
since most of the functionality is in that IO callback, it was hard to 
catch earlier.

Thanks for bearing with me,
John


John Christian wrote:

> Hi There,
>
> Ok, here's the gist of what I'm doing, a lot of excess code snipped 
> off, hopefully it's
> legible enough to illustrate what I'm trying to do, I've added 
> additional comments
> to describe what's happening:
>
> (The server code is split up into several modules but still in one 
> file, and methods
> are shared by @ISA relationships):
>
> # file: Server.pm
>
> package SCUMD::Server;
>
> use Event;
>
> @ISA = qw/SCUMD::Server::Jobs ... /;
>
> @EXPORT = qw/new run/;
>
> [ ... ]
>
> # new just loads configs and creates a blessed reference
>
> sub arm {
>    my($h);
>    $h = shift @_;
>
>    Event->signal(signal => 'HUP',
>                  cb     => [ $h, '_cb_hup'],
>          desc   => 'HUP signal handler');
>
>    # init_socket, returns plain server socket:
>    # through the server socket can come requests
>    # which can result in the creation of Event::timer objects
>    # while in the event loop:
>
>    Event->io(fd   => $h->init_socket(),
>          cb   => [ $h, 'io_callback' ],
>          desc => 'server socket watcher');
> }
>
> # run: besides "new", it's the only method Exported to be called
> # by driver code:
>
> sub run {
>    my($h);
>    $h = shift @_;
>
>    $h->log_info("arming default event handlers");
>
>    $h->arm();
>
>    $h->log_info("entering standard server state");
>
>    # enter event loop:
>    Event::loop();
> }
>
> [ ... ]
>
> package SCUMD::Server::Jobs;
>
> use Event;
>
> # job_create: this subroutine gets called as a method by a protocol 
> handler, which
> # is in turn called by the io callback:
>
> sub job_create {
>    my($h, %p, $time, $unit, $tmp, $jid, $iter, $interval, $abstime, $now,
>       $set, $timer);
>
>    ($h, %p) = @_;
>
> [ ... ]
>
>    # create a timer to push jobs onto the queue:
>    # $abstime is computed using DateTime::Event::Cron, which returns
>    # an interval with is added to the current time:
>    # BUT ... even when testing this callback with a hardcoded interval
>    # of a few seconds ... it's NEVER executed!
>
>    $timer = Event->timer(at => $abstime,
>              desc => "recurring job performing $p{task}",
>              cb => sub {
>                  print STDERR "job timer callback!\n";
>                  $h->log_info("enqueuing job jid $jid for $p{who}");
>                  $h->enqueue(%p);
>                                  # reset timer interval to next 
> interation:
>                  $interval = ($iter->next - DateTime->now)->seconds;
>                  $now      = int timelocal(0,0,0,(localtime)[3,4,5]);
>                  $abstime  = $interval + $now;
>                  $h->log_info("resetting timer with absolute time 
> $abstime (in ".$interval.
>                       " seconds");
>                  $timer->at($abstime);
>              });
>
>    $h->log_info("arming test timer (10 sec interval)");
>
>    # test timer to see if stuff is actually happening ... it's 
> callback never seems to get executed, as well:
>
>    Event->timer(
>         interval => 10,
>         desc     => "test timer producing output every 10 seconds",
>         prio     => &PRIO_HIGH,
>         cb       => sub {
>             $h->log_info("callback for test timer called!!!");
>         });
>
>    $tmp = {
>    who   => $p{who},
>    info  => { %p },
>    jid   => $jid,
>    timer => $timer
>    };
>
>    # push(@Jobs, $tmp);
>    $JobsByJID{$jid} = $tmp;
>
>    # at this point, if I call Event::all_watchers, it does return
>    # watchers for timers and the io callback, reporting them all
>    # as active.  I'd think this would allay any suspicion that it's
>    # a scoping issue.
>
> }
>
> The file in its entirety can be seen at : 
> http://cvs.sourceforge.net/viewcvs.py/*checkout*/scumd/scumd/lib/SCUMD/Server.pm?content-type=text%2Fplain&rev=1.5 
>
>
>
> Jochen Stenzel wrote:
>
>> Hello, John,
>>
>> JC> The timer watchers created are returned when I do a
>> JC> all_watchers(), but their callbacks are NEVER subsequently
>> JC> executed (even with PRIO_HIGH and a hardcoded short interval).
>>
>> JC> Is there anything more I may need to do for the timers to be active?
>>
>> you just have to build the (active) watchers. Could you send a piece
>> of code to the list to demonstrate your algorithm?
>>
>> I'm wondering that you mention all_watchers(), but I don't know the
>> code, so it would be interesting. I'd suggest to call Event's timer()
>> method from within the callback of the io watcher.
>>  
>>
> Right, that's what I'm trying, but the timers I've created are 
> curiously never executed, all_watchers()
> just (presumably) confirms that they are present and active within 
> Event's internal watcher list.
>
>> JC> Also, if there is more documentation available in addition to the 
>> JC> perldoc, that would be very helpful.
>>
>> There's a tutorial coming with the Event package, in PDF format.
>>
>> Greetings
>>
>>         Jochen
>>
>>        
>>  
>>
> So I take it I am supposed to be able to create timers while in the 
> event loop?  To me, that seemed like
> that most likely culprit to my troubles here, but the Pod docs for 
> Event really don't specifically say.
>
> Any input appreciated.
>
> Thanks,
> John
>