Get status of loop.call_later call

58 views
Skip to first unread message

Alexander Shorin

unread,
May 7, 2015, 8:13:54 PM5/7/15
to python...@googlegroups.com
Hi,

Excuse me if such trivial questions were already answered, but I failed to find any traces of them.

Assume I want to make a delayed call:

    handler = loop.call_later(delay, callback)

How can I check if callback was called for _now_?
Handler seems only provides a way to cancel a call, not to check it status: is called, failed with exception etc.

If the callback failed, how can I get an exception of it?
loop.set_exception_handler seems is designed to catch everything, but I need to catch exact that callback failure.

Bonus: what's the best way to delay call (delay yield from) coroutines? I guess is something like that:

    @asyncio.coroutine
    def yield_later(delay, coro):
        yield from asyncio.sleep(delay)
        yield from coro

    asyncio.async(yield_later(delay, mycoro(foo, bar=baz)))

but just want to make sure.

For now, the only solution I see is about wrap callback with additional functions in order to catch and process raised exceptions, set an Event in order to notify callee about callback call and so on, but doing all this I have a strange feel that I miss something oblivious. So do I?

--
,,,^..^,,,


coles...@gmail.com

unread,
May 7, 2015, 8:54:23 PM5/7/15
to Alexander Shorin, python-tulip
Hi Alexander,

I don't believe there's any way which which you can check the result
of a callback from the Handle. You would have to use something like a
Future passed into your callback.
You can also use this future to capture any potential exceptions
thrown in the callback.

def callback(arg, future):
try:
result = int(arg)
future.set_result(result)
except Exception as e:
future.set_exception(e)


if __name__ == "__main__":
loop = asyncio.get_event_loop()

print("Schedule callback")
future = asyncio.Future() # Future to capture result
loop.call_later(5, callback, "42", future)

print("Wait for result")
print("Result: %d" % loop.run_until_complete(future))


One I've seen to delay scheduling of a coroutine or Future is to just
use `call_later`:

@asyncio.coroutine
def test_coro(delay, loop):
loop.call_later(delay, asyncio.async, mycoro())


The downside to this is you can't capture any result or exception from
`mycoro` since this discards the Task returned by `asyncio.async`.
If you wanted the result of mycoro, then your approach of scheduling a
coroutine which delays the target coroutine seems pretty concise. Just
remember to `yield from` the Task returned from `asyncio.async` when
you need the result.

Happy coding.
David

Guido van Rossum

unread,
May 7, 2015, 8:55:16 PM5/7/15
to Alexander Shorin, python-tulip
On Thu, May 7, 2015 at 5:13 PM, Alexander Shorin <kxe...@gmail.com> wrote:
Assume I want to make a delayed call:

    handler = loop.call_later(delay, callback)

How can I check if callback was called for _now_?

You can't.
 
Handler seems only provides a way to cancel a call, not to check it status: is called, failed with exception etc.

Correct.
 
If the callback failed, how can I get an exception of it?

It will be logged, but you can't catch and examine it.
 
loop.set_exception_handler seems is designed to catch everything, but I need to catch exact that callback failure.

Correct, that's not meant for this use case.
 
Bonus: what's the best way to delay call (delay yield from) coroutines? I guess is something like that:

    @asyncio.coroutine
    def yield_later(delay, coro):
        yield from asyncio.sleep(delay)
        yield from coro

    asyncio.async(yield_later(delay, mycoro(foo, bar=baz)))

but just want to make sure.

But what are you doing with the return from the async() call?
 
For now, the only solution I see is about wrap callback with additional functions in order to catch and process raised exceptions, set an Event in order to notify callee about callback call and so on, but doing all this I have a strange feel that I miss something oblivious. So do I?

That's indeed how you do this.

Remark: you are mixing questions about callbacks and coroutines. Maybe you are not entirely sure about the difference between the two? They are meant to be used at quite different levels (in fact, coroutines make progress mostly when the event loop calls some callback that causes a Task or Future to become done).

--
--Guido van Rossum (python.org/~guido)

Alexander Shorin

unread,
May 8, 2015, 5:59:29 AM5/8/15
to python-tulip
Alright, so my suspicions are verified. Thanks!
--
,,,^..^,,,
Reply all
Reply to author
Forward
0 new messages