On 2008-01-17 12:02, Jason Tackaberry wrote:
>     cb = kaa.ThreadCallback('thumbnailer', generate_thumbnail)
>     cb('file.jpg').connect(handle_thumbnail_done)
>   

I still like this API but I see a race condition here: if the thread
executes and completes before connect() is called, handle_thumbnail_done
will never see the result.  This isn't a problem for coroutines since
it's all confined to a single thread.  This is fixable by attaching an
internal handler that caches the result, and next time something
connects to the InProgress returned by __call__ it emits the cached result.

In fact, this functionality could be pushed down to the Signal class. 
Have a new method Signal.emit_deferred or something which will cache the
args and emit them after the next handler is attached.

On a related note, I'd like to update the yield_execution() decorator so
that it returns an InProgress in every case.  I recently updated it to
just return the result if the decorated function doesn't yield anything
(rather than before where it assumed there was a next member and if
there wasn't raised an exception), but on second thought I think this is
a bad idea.  I think yield_execution should return an InProgress object
no matter what, so that the caller is guaranteed to be able to connect
to its return value.  Here we can again use the Signal.emit_deferred method.

I would also like it so that if the decorated function yields _anything_
(including None) it is automatically continued.  I guess I never
understood why it should be necessary to yield YieldContinue?  If I have
a function decorated with yield_execution and I yield something, when
would I _not_ want it to be continued?  So I'd like it that if it yields
nothing (None), it behaves like YieldContinue, and if it yields a
result, the InProgress signal is emitted with the result, and then it
behaves like YieldContinue.  In other words, I want to deprecate
YieldContinue.

So:

    @kaa.yield_execution()
    def foo():
       return 42

    @kaa.yield_execution()
    def bar():
       yield 42

    @kaa.yield_execution()
    def baz():
       for i in range(10):
          yield i

    @kaa.yield_execution()
    def zap():
       result = []
       while do_some_work(result):
          yield
       yield result

    def handler(result):
       print "Result", result

    foo().connect(handler)
    bar().connect(handler)
    baz().connect(handler)
    zap().connect(handler)
      


In the foo and bar cases, handler is called with the value 42, even
though the functions actually complete before the handler is connected. 
(So Signal.emit_deferred will accomplish this.)

In the baz case, handler is called 10 times, for each value.

In the zap case, the function yields execution a number of times and the
notifier loop periodically reenters it, until finally it yields result,
and handler gets invoked with the result.  (zap.next would be called
once more after that, but it will immediately raise StopExecution and
then it will not be called again.)

Thoughts?


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Freevo-devel mailing list
Freevo-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freevo-devel

Reply via email to