Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Asynchronous cell execution #6

Closed
wants to merge 10 commits into from
Closed

[WIP] Asynchronous cell execution #6

wants to merge 10 commits into from

Conversation

davidbrochart
Copy link
Member

This PR allows for asynchronous cell execution. I just duplicated (with an async_ prefix) and made asynchronous the run_cell method and all its callers for now.
An option would be to keep only the async version of the methods and provide a user-facing (non-async) execute method that would accept a asynchronous=False parameter. If False, execute would under the hood emulate a blocking call by running async_execute in the event loop with run_until_complete().

@davidbrochart davidbrochart changed the title Asynchronous cell execution [WIP] Asynchronous cell execution Jan 29, 2020
polling_exec_reply = True

while more_output or polling_exec_reply:
await asyncio.sleep(0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, what is the purpose of this await?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It just yields, so that the event loop can run other tasks.

@akhmerov
Copy link
Member

I don't quite understand how this works: the part where it makes sense to await is the kernel client events, but we're not actually awaiting on anything there, as far as I can see.

@davidbrochart
Copy link
Member Author

The purpose of this PR is just to be able to execute several notebooks in parallel in an async context. Previously it could only be done using threads, because this while loop is blocking.


# Avoid exceeding the execution timeout (deadline), but stop
# after at most 1s so we can poll output from iopub_channel.
timeout = self._timeout_with_deadline(1, deadline)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akhmerov I think I see what you mean. In practice it allows for some degree of concurrency, because of this 1s timeout, so other cells can be run every second.

@davidbrochart
Copy link
Member Author

The user-facing execute method calls async_execute until it completes (same behavior as before). async_execute is an asynchronous method that allows executing several notebooks concurrently in an async context. At the lowest level, we poll for messages and block for 0.1 second so that other cells can be run.
I guess that if we truly want async all the way we should have an async version of jupyter_client's get_msg that would return a Future from zmq.asyncio.Socket.poll().

@davidbrochart
Copy link
Member Author

Trigger CI.

@davidbrochart davidbrochart reopened this Jan 30, 2020
@davidbrochart
Copy link
Member Author

@akhmerov although the tests sometimes fail in the CI (due to very slow machines I guess), I think this is ready to be reviewed. Because jupyter_client's get_msg uses zmq.Socket.poll() which is blocking, I had to poll on get_msg in a non-blocking way (no timeout). But once we get get_msg to use zmq.asyncio.Socket.poll() in jupyter_client, we will be able to await get_msg. Nevertheless I think this PR demonstrates that by having async execution methods we can already have concurrency without using threads.

@davidbrochart davidbrochart mentioned this pull request Feb 2, 2020
@davidbrochart
Copy link
Member Author

Closing as #10 has been merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants