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

fix: ensure_async should not silently eat errors and return the coro instead of the result #138

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

maartenbreddels
Copy link
Contributor

We are now returning the coroutine itself, instead of the results of the coroutine.

This gets triggered when a coroutine that is wrapped actually awaits the same coroutine twice. In my case in voila, this caused kernel_id https://github.com/voila-dashboards/voila/blob/4b323460fd5d7e6a7203ff0492607c13c8eb6f25/voila/handler.py#L166 to be assigned the coroutine, because the start_kernel had an exception.

Note that this change causes the tests to fail, I'm not sure how to fix this.

@@ -81,13 +81,6 @@ async def ensure_async(obj: Union[Awaitable, Any]) -> Any:
and await it if it was not already awaited.
Copy link
Member

Choose a reason for hiding this comment

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

The docstring has to be changed too, since we always await if the object is a coroutine.

@davidbrochart
Copy link
Member

The code you removed was here to handle the error that you see in the tests: ensure_async is passed a coroutine that was already awaited, so you can't await it again.

@maartenbreddels
Copy link
Contributor Author

Yes, but with the current code, the second call will return a coro, which I assume is always True, so the logic will not be correct. Testing this:
image

I think it doesn't make sense we cannot call is_alive twice, should we fix that instead?

@davidbrochart
Copy link
Member

this caused kernel_id https://github.com/voila-dashboards/voila/blob/4b323460fd5d7e6a7203ff0492607c13c8eb6f25/voila/handler.py#L166 to be assigned the coroutine, because the start_kernel had an exception.

But in this case ensure_async should have raised the exception, and kernel_id should not be assigned the coroutine, right?

@maartenbreddels
Copy link
Contributor Author

No, because the exception raised was RuntimeException - cannot reuse already awaited coroutine, so ensure_async returned the coro

@davidbrochart
Copy link
Member

So this means that self.kernel_manager.start_kernel() returned twice the same coroutine?
Are you working on the Voila feature that pre-launches kernels by any chance? If that's the case, I suspect that the second time you call it you are passing the coroutine itself instead of its return value.

@maartenbreddels
Copy link
Contributor Author

So this means that self.kernel_manager.start_kernel() returned twice the same coroutine?

Almost :), inside start_kernel I accidentally awaited a coro twice, and indeed, this is for voila-dashboards/hotpot_km#2. Note that this was a programmer mistake, not a runtime issue, but it didn't surface (the exception was not raised due to ensure_async). This costed me a lot of time, so I thought we probably want to avoid this in the future.

@davidbrochart
Copy link
Member

I agree that the code you removed in this PR should not have been there, and it was mostly to fix an issue that I didn't fully understand. We should probably fix is_alive() as you mentioned, because it shouldn't return twice the same coroutine.

@maartenbreddels
Copy link
Contributor Author

maartenbreddels commented Mar 5, 2021 via email

@davidbrochart
Copy link
Member

I've looked too, but jupyter-client is becoming really complicated. I opened jupyter/jupyter_client#621.

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