-
Notifications
You must be signed in to change notification settings - Fork 231
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
Asyncio and coroutine synchronization support? #236
Comments
Can you explain better what you think it needs to do and what would need to change in the implementation? Is it just a matter of it it using I wasn't even aware that asyncio had locks so know nothing about them and how they are used. |
Thanks for the reply. To begin, asycio locks are awaited (their Also (I assume) they would not be reentrant as it would basically allow the single thread servicing the event loop (and executing most/all the coroutines in the program, perhaps even concurrently) to go basically anywhere without any restrictions. And because wrapper of a coroutine itself needs to be a coroutine (a chain of Also if we couple this to the present feature in Hope this was somewhat helpful. |
Quick note on wrapping either sync-or-async, since I've done this in |
I think adapting |
Even if you can come up with a separate |
OK, will work on it. Just paste here for now, or propose in a PR? |
Just follow up here initially with any conclusions you come to. My feeling right now is that an |
Correction:
... on the return value of the wrapped function, to determine if it is an awaitable or not. My point was that inspecting the function (as with
That last method will work 100% of the time in all cases, but it can be trickier (or in some cases impossible) to write the logic in a way that can only decide how to act after calling the possibly-async function. Take a look at how I've got it implemented in The downside of just using the So the ideal wrapper combines these technique. Here's an untested/incomplete sketch of what that might look like: def wrapper(function):
if inspect.iscoroutinefunction(function) or inspect.iscoroutinefunction(function.__call__):
async def _wrapper(*args, **kwargs):
async with lock:
return function(*args, **kwargs)
else:
def _wrapper(*args, **kwargs):
result = function(*args, **kwargs)
if inspect.isawaitable(result):
async def _finish():
async with lock:
return await result
return _finish() # `await` intentionally omitted
else:
return result
return _wrapper |
FWIW, old example which tries to deal with sync or async functions. Based on comments above though, that too probably needs more work to be complete, but important in that example is that it still uses |
!!! 3.12 added I think this tips the balance strongly in favor of: if a function returns an awaitable object but doesn't pass If I had to re-design Personally, I think it's fine for (In fact, it might be possible to backport |
Thanks for
wrapt
.I was wondering if you are going to add support for synchronizing coroutines (using
@synchronized
decorator) and acceptingasyncio Locks
to wrapt? Currently it does not accept asyncio locks.Also because ayncio model is mostly single-threaded but highly re-entrant, rlocks (which are more suitable for parallel scenarios) would not work (I think).
The text was updated successfully, but these errors were encountered: