Repository navigation
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
greenletsin cases wherenest_asynciocannot be used (e.g. usinguvloopevent loop).This alternative path works by using
greenletto 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