Skip to content

Use async functions in sync context to avoid code duplication. #565

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

Open
wants to merge 9 commits into
base: gh/zdevito/44/base
Choose a base branch
from

Conversation

zdevito
Copy link
Contributor

@zdevito zdevito commented Jul 17, 2025

Stack from ghstack (oldest at bottom):

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.

Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: D78466520

NOTE FOR REVIEWERS: This PR has internal Meta-specific changes or comments, please review them on Phabricator!

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)

**NOTE FOR REVIEWERS**: This PR has internal Meta-specific changes or comments, please review them on [Phabricator](https://our.internmc.facebook.com/intern/diff/D78466520/)!

[ghstack-poisoned]
zdevito added a commit that referenced this pull request Jul 17, 2025
We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)

**NOTE FOR REVIEWERS**: This PR has internal Meta-specific changes or comments, please review them on [Phabricator](https://our.internmc.facebook.com/intern/diff/D78466520/)!

ghstack-source-id: 296756465
Pull Request resolved: #565
@meta-cla meta-cla bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jul 17, 2025
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D78466520

…ion."

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)

**NOTE FOR REVIEWERS**: This PR has internal Meta-specific changes or comments, please review them on [Phabricator](https://our.internmc.facebook.com/intern/diff/D78466520/)!

[ghstack-poisoned]
zdevito added a commit that referenced this pull request Jul 17, 2025
Pull Request resolved: #565

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)
ghstack-source-id: 296927735
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D78466520

…ion."

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)

**NOTE FOR REVIEWERS**: This PR has internal Meta-specific changes or comments, please review them on [Phabricator](https://our.internmc.facebook.com/intern/diff/D78466520/)!

[ghstack-poisoned]
zdevito added a commit that referenced this pull request Jul 17, 2025
Pull Request resolved: #565

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.
ghstack-source-id: 296934588

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D78466520

…ion."

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)

**NOTE FOR REVIEWERS**: This PR has internal Meta-specific changes or comments, please review them on [Phabricator](https://our.internmc.facebook.com/intern/diff/D78466520/)!

[ghstack-poisoned]
zdevito added a commit that referenced this pull request Jul 18, 2025
Pull Request resolved: #565

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.
ghstack-source-id: 297091858

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D78466520

…ion."

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)

**NOTE FOR REVIEWERS**: This PR has internal Meta-specific changes or comments, please review them on [Phabricator](https://our.internmc.facebook.com/intern/diff/D78466520/)!

[ghstack-poisoned]
zdevito added a commit that referenced this pull request Jul 18, 2025
Pull Request resolved: #565

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.
ghstack-source-id: 297094308

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D78466520

…ion."

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)

**NOTE FOR REVIEWERS**: This PR has internal Meta-specific changes or comments, please review them on [Phabricator](https://our.internmc.facebook.com/intern/diff/D78466520/)!

[ghstack-poisoned]
zdevito added a commit that referenced this pull request Jul 18, 2025
Pull Request resolved: #565

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

See [avoiding async code duplication] in the diff for a description of the approach.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. To indicate to the synchronous actor that it is ok to `get()` despite this setup, we temporarily blank out the running asyncio loop while a asynchronous actor is running a message. We need to eventually figure out a way to get the synchronous actors running on a thread that truly is not the asyncio event loop.

ghstack-source-id: 297098923

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D78466520

…ion."

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)

**NOTE FOR REVIEWERS**: This PR has internal Meta-specific changes or comments, please review them on [Phabricator](https://our.internmc.facebook.com/intern/diff/D78466520/)!

[ghstack-poisoned]
zdevito added a commit that referenced this pull request Jul 18, 2025
Pull Request resolved: #565

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

See [avoiding async code duplication] in the diff for a description of the approach.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. To indicate to the synchronous actor that it is ok to `get()` despite this setup, we temporarily blank out the running asyncio loop while a asynchronous actor is running a message. We need to eventually figure out a way to get the synchronous actors running on a thread that truly is not the asyncio event loop.

ghstack-source-id: 297182373

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D78466520

…ion."

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)

**NOTE FOR REVIEWERS**: This PR has internal Meta-specific changes or comments, please review them on [Phabricator](https://our.internmc.facebook.com/intern/diff/D78466520/)!

[ghstack-poisoned]
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D78466520

…ion."

We currently have a lot of code duplication for blocking/nonblocking variants.

This PR lets the blocking variants be defined in terms of the async ones.

It first directly exposes the tokio Future object to python, letting it choose to synchronously block on it, or turn it into a asyncio.Future. Then when we are running async code to do pipe receives in a sync context, we can skip running a real event loop and just step the coroutine manually.

TODO: expand writeup.


Currently there is jank around the fact that we are running synchronous actor code on a thread that already has a running event loop. I put in a workaround with a comment, but we should resolve this by not running the sync code on the asyncio loop.

Differential Revision: [D78466520](https://our.internmc.facebook.com/intern/diff/D78466520/)

**NOTE FOR REVIEWERS**: This PR has internal Meta-specific changes or comments, please review them on [Phabricator](https://our.internmc.facebook.com/intern/diff/D78466520/)!

[ghstack-poisoned]
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D78466520

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Meta Open Source bot. fb-exported
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants