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

Nick Coghlan ncoghlan at gmail.com
Sat Jul 11 12:17:22 CEST 2015


On 11 July 2015 at 15:16, Nathaniel Smith <njs at pobox.com> wrote:
> For what it's worth, I find it extraordinarily confusing that background
> tasks don't run in the background and foreground tasks don't run in the
> foreground.

I think the core problem lies in trying to reduce "the bare minimum
you need to know to work effectively with native coroutines" to only
two concepts, when there's actually three:

* scheduling a coroutine in the event loop without waiting for it
* executing a call in a background thread or process
* running the event loop in the foreground while waiting for one of
the above two operations

I'm trying to do this *without* requiring folks to actually know what
a future is: I want them to be able to use asyncio *without* learning
about all the moving parts first. Once they appreciate what it can do
for them, *then* they may have the motivation to tackle the task of
figuring out how all the pieces fit together.

However, In the design I put together for the blog posts,
"run_in_background" currently handles both of the first two tasks, and
it likely makes more sense to split them, which would give:

def run_in_foreground(task, *, loop=None):
    """Runs the given event loop in the current thread until the task completes

    If not given, *loop* defaults to the current thread's event loop

    Returns the result of the task.

    For more complex conditions, combine with asyncio.wait()
    To include a timeout, combine with asyncio.wait_for()
    """
    # Convenience wrapper around get_event_loop +
    # ensure_future + run_until_complete
    ...

def schedule_coroutine(target, *, loop=None):
    """Schedules target coroutine in the given event loop

    If not given, *loop* defaults to the current thread's event loop

    Returns the scheduled task.

    Use run_in_foreground to wait for the result.
    """
    # This just means extracting the coroutine part of
    # asyncio.ensure_future out to its own function.
    ...

def call_in_background(target, *, loop=None, executor=None):
    """Schedules and starts target callable as a background task

    If not given, *loop* defaults to the current thread's event loop
    If not given, *executor* defaults to the loop's default executor

    Returns the scheduled task.

    Use run_in_foreground to wait for the result.
    """
    # Convenience wrapper around get_event_loop + run_in_executor
    ...

I'll sleep on that, and if I still like that structure in the morning,
I'll look at revising my coroutine posts.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-ideas mailing list