[Python-ideas] Learning from the shell in supporting asyncio background calls

Guido van Rossum guido at python.org
Fri Jul 10 13:51:37 CEST 2015

As I wrote on the issue, I'm -1 on this proposal. Not only does this API
encourage beginners to ignore the essential difference between synchronous
functions meant to run in a thread (using synchronous I/O and pre-emptive
CPU scheduling) and asyncio coroutines/tasks (which use overlapped I/O and
require explicit scheduling), it also encourages avoiding the "await"
primitive (formerly "yield from") in favor of a function call which cannot
be used from within a coroutine/task.

This particular spelling moreover introduces a "similarity" between
foreground and background tasks that doesn't actually exist.

The example suggests that this should really be a pair of convenience
functions in collections.futures, as it does not make any use of asyncio.

On Fri, Jul 10, 2015 at 12:49 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:

> Hi folks,
> Based on the recent discussions Sven kicked off regarding the
> complexity of interacting with asyncio from otherwise synchronous
> code, I came up with an API design that I like inspired by the way
> background and foreground tasks in the POSIX shell work.
> My blog post about this design is at
> http://www.curiousefficiency.org/posts/2015/07/asyncio-background-calls.html
> ,
> but the essential components are the following two APIs:
>     def run_in_background(target, *, loop=None):
>         """Schedules target as a background task
>         Returns the scheduled task.
>         If target is a future or coroutine, equivalent to
> asyncio.ensure_future
>         If target is a callable, it is scheduled in the default executor
>         """
>         ...
>     def run_in_foreground(task, *, loop=None):
>         """Runs event loop in current thread until the given task completes
>         Returns the result of the task.
>         For more complex conditions, combine with asyncio.wait()
>         To include a timeout, combine with asyncio.wait_for()
>         """
>         ...
> run_in_background is akin to invoking a shell command with a trailing
> "&" - it puts the operation into the background, leaving the current
> thread to move on to the next operation (or wait for input at the
> REPL). When coroutines are scheduled, they won't start running until
> you start a foreground task, while callables delegated to the default
> executor will start running immediately.
> To actually get the *results* of that task, you have to run it in the
> foreground of the current thread using run_in_foreground - this is
> akin to bringing a background process to the foreground of a shell
> session using "fg".
> To relate this idea back to some of the examples Sven was discussing,
> here's how translating some old serialised synchronous code to use
> those APIs might look in practice:
>     # Serial synchronous data loading
>     def load_and_process_data():
>         data1 = load_remote_data_set1()
>         data2 = load_remote_data_set2()
>         return process_data(data1, data2)
>     # Parallel asynchronous data loading
>     def load_and_process_data():
>         future1 = asyncio.run_in_background(load_remote_data_set1_async())
>         future2 = asyncio.run_in_background(load_remote_data_set2_async())
>         data1 = asyncio.run_in_foreground(future1)
>         data2 = asyncio.run_in_foreground(future2)
>         return process_data(data1, data2)
> The application remains fundamentally synchronous, but the asyncio
> event loop is exploited to obtain some local concurrency in waiting
> for client IO operations.
> Regards,
> Nick.
> P.S. time.sleep() and asyncio.sleep() are rather handy as standins for
> blocking and non-blocking IO operations. I wish I'd remembered that
> earlier :)
> --
> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/

--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150710/83565dd1/attachment.html>

More information about the Python-ideas mailing list