asyncio loop.call_soon()

Terry Reedy tjreedy at udel.edu
Tue Nov 28 14:25:52 EST 2017


On 11/28/2017 11:02 AM, Ian Kelly wrote:
> On Tue, Nov 28, 2017 at 8:30 AM, ast <nomail at com.invalid> wrote:
>> Hello
>>
>> Python's doc says about loop.call_soon(callback, *arg):
>>
>> Arrange for a callback to be called as soon as possible. The callback is
>> called after call_soon() returns, when control returns to the event loop.
>>
>> But it doesn't seem to be true; see this program:
>>
>> import asyncio
>>
>> async def task_func():
>>     print("Entering task_func")
>>
>> def callback():
>>     print("Entering callback")
>>
>> async def main():
>>     print("Entering main")
>>     task = loop.create_task(task_func())
>>     loop.call_soon(callback)
>>     await task
>>
>> loop = asyncio.get_event_loop()
>> loop.run_until_complete(main())
>>
>> Execution provides following output:
>>
>> Entering main
>> Entering task_func
>> Entering callback
>>
>> callback is executed AFTER task_func, I expected it
>> to be executed BEFORE.
>>
>> When "main()" coroutine reach line "await task", it let the control to the
>> event loop, and it seems that the loop starts to execute task instead of
>> callback. Then, when task is over the loop runs callback
>>
>> This is not what the doc says: callback should be called as soon
>> as possible when the loop has control, with a priority over other
>> tasks pending in the loop
> 
> You omitted this part of the documentation:
> 
> "This operates as a FIFO queue, callbacks are called in the order in
> which they are registered. Each callback will be called exactly once."
> 
> This documents the ordering of call_soon callbacks. It doesn't say
> anything about how the callback will be ordered with respect to tasks
> or other events that are also immediately ready to be handled.
> 
> Also, if you look at the implementation of create_task, it invokes
> call_soon. This is therefore consistent with the doc, as call_soon was
> actually called twice: first for task_func(), and then for callback.

I believe that this means that any code in the coroutine *before* the 
first await is run immediately.  This is what I experienced in my 
experiments yesterday.


-- 
Terry Jan Reedy




More information about the Python-list mailing list