-
Notifications
You must be signed in to change notification settings - Fork 78
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
Replace nest_asyncio with greenlets #683
Replace nest_asyncio with greenlets #683
Conversation
908f38e
to
6d5be35
Compare
4b053b4
to
53e878a
Compare
PR updated with:
|
33f437b
to
23db634
Compare
23db634
to
cb9cd9a
Compare
PR updated with exception handling in coroutine and exception injection with |
cb9cd9a
to
5c7dae5
Compare
PR updated with:
|
5c7dae5
to
140f438
Compare
PR updated with extra comments. I now consider it ready so I'll remove the |
Found an issue, please do not merge as-is. EDIT: the issue is the following: def __enter__(self, *args, **kwargs):
return run(self.cm.__aenter__(*args, **kwargs))
def __exit__(self, *args, **kwargs):
return run(self.cm.__aexit__(*args, **kwargs)) This is fine as long as
Issue 1. can be worked around by hijacking the mechanism the event loop uses to be aware of new async gen. However, issue 2. is more tricky and is probably a real issue if e.g. the async generator tries to take an asyncio.Lock() across I'll experiment to see what possibilities exist to fix this problem. This is fortunately the only place that relies on migrating a coroutine between multiple event loops. Trio encountered a similar problem: python-trio/trio#2081 |
140f438
to
be55415
Compare
PR updated with:
|
@marcbonnici, Vincent Coubard, Branislav Rankov, this should be ready for the last review/testing round. I consider it to be ready. |
be55415
to
c30eb53
Compare
PR rebased. As of today we started dogfooding that PR in LISA's vendored devlib tree, so it should get some more real-world exposure in the coming weeks. |
c30eb53
to
f384a4d
Compare
PR updated with extra tests to check the blocking API works when invoked from |
f384a4d
to
a237603
Compare
PR updated with a fix to use |
a237603
to
ab193ed
Compare
PR rebased |
d071e9d
to
7645db7
Compare
Update with a check to only call loop.shutdown_default_executor() if it exists, since it was added in Python 3.9 https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.shutdown_default_executor |
An issue was found, I'm currently working on fixing it, please do not merge until it's fixed. |
7645db7
to
458f6c1
Compare
PR updated with:
|
One thing I realized and might want to change is that if an event loop is already running (e.g. in a jupyterlab notebook), we will dispatch the coroutine on a loop setup in a separate thread. It's all good except we have a single such thread. This means that code making parallel devlib invocation of devlib in threads with a pre-setup event loop will end up being serialized. It shouldn't be very hard to change, I'll see if I can do that tomorrow |
Set the "_name" attribute rather than trying to set the "name" read-only property.
Once a thread exits, the connection instance it was using can be returned to the pool so it can be reused by another thread. Since there is no per-thread equivalent to atexit, this is achieved by returning the connection to the pool after every top-level method call that uses it directly, so the object the user can get by accessing Target.conn can change after each call to Target method.
Prepare for providing our own implementation of asyncio.run() to work without nest_asyncio package.
Provide an implementation of re-entrant asyncio.run() that is less brittle than what greenback provides (e.g. no use of ctypes to poke extension types). The general idea of the implementation consists in treating the executed coroutine as a generator, then turning that generator into a generator implemented using greenlet. This allows a nested function to make the top-level parent yield values on its behalf, as if every call was annotated with "yield from".
458f6c1
to
587d8c7
Compare
PR updated with:
Considered it is a substantial change, I'd be more comfortable dogfooding it in LISA for a little while before we consider merging it. |
1.5 month later there has been no reported issue, so I think it's good to go |
Considering #682, this PR updates devlib to use
greenlets
in cases wherenest_asyncio
cannot be used (e.g. usinguvloop
event loop).This alternative path works by using
greenlet
to provide a way for nested coroutines separated from the top-level coroutine by blocking calls to yield their action.TODO:
__await__
, so that they are propagated to the correct coroutine rather than the top-level oneFixes #682