[PEAK] removing deferred calls (addition to the `callLater` method)

Phillip J. Eby pje at telecommunity.com
Fri Jul 16 11:56:44 EDT 2004

At 06:28 PM 7/16/04 +0300, Yaroslav Samchuk wrote:
>What do you thing about adding a method (let's call it `removeLater` or
>`cancelLater`) to a scheduler (or, may be, somewhere else), which will
>remove deffered call using, let's say, any identifier, which `callLater`
>could return. This identifier, of couse, must be unique for all
>currently existed laters.
>In my opinion it could be really interesting, if we wanted to deffer a
>call of any method, but considering some circumstances we have to
>terminate a component not firing that method.
>May be you have a machinery, which could do this, but I don't know that?

Yes, there is.  In Twisted, one needs to be able to cancel callbacks 
because one generally uses only callbacks to run code later.  In PEAK, the 
canonical way to wait a time period is:

     def aTask(args):
         yield scheduler.sleep(seconds); events.resume()

And then you can simply check your condition immediately following the 
events.resume() call.  Or, if you want to resume as soon as that or another 
event happens, you can use something like:

     def aTask(args):
         sleep = scheduler.sleep(seconds)
         readable = scheduler.readable(someSocket)
         untilReadableOrTimeout = events.AnyOf(sleep,readable)

          yield untilReadableOrTimeout; source = events.resume()

         if source is readable:
             # read data
             # got timeout

So, if you use tasks to manage your control flow, there isn't actually any 
need to cancel anything.  One other option that you can use is 
events.Interrupt (or scheduler.alarm()), that allows you to start a 
procedure, and if the interrupt event (or timeout) occurs before the task 
is completed, an error will be raised inside the procedure.  e.g.:

     yield scheduler.alarm(someGenerator(args), timeoutSeconds)
     result = events.resume()

This will raise a TimeoutError inside someGenerator if the timeout expires 
before the generator returns a value.  The subsequent statement retrieves 
the result returned by the generator, or re-raises the TimeoutError in the 
current frame, if the timeout occurred.

So, so far I have not needed to cancel a callback in any of the code I have 
written for peak.events.  If you have a use case that doesn't fit well into 
these approaches, please describe it for me and perhaps we can add 
something.  Thanks.

More information about the PEAK mailing list