Issue
I may may need help phrasing this question better. I'm writing an async api interface, via python3.7, & with a class (called Worker()
). Worker
has a few blocking methods I want to run using loop.run_in_executor()
.
I'd like to build a decorator I can just add above all of the non-async
methods in Worker
, but I keep running into problems.
I am being told that I need to await
wraps()
in the decorator below:
def run_method_in_executor(func, *, loop=None):
async def wraps(*args):
_loop = loop if loop is not None else asyncio.get_event_loop()
return await _loop.run_in_executor(executor=None, func=func, *args)
return wraps
which throws back:
RuntimeWarning: coroutine 'run_method_in_executor.<locals>.wraps' was never awaited
I'm not seeing how I could properly await
wraps()
since the containing function & decorated functions aren't asynchronous. Not sure if this is due to misunderstanding asyncio
, or misunderstanding decorators.
Any help (or help clarifying) would be greatly appreciated!
Solution
Not_a_Golfer answered my question in the comments.
Changing the inner wraps()
function from a coroutine into a generator solved the problem:
def run_method_in_executor(func, *, loop=None):
def wraps(*args):
_loop = loop if loop is not None else asyncio.get_event_loop()
yield _loop.run_in_executor(executor=None, func=func, *args)
return wraps
Edit:
This has been really useful for IO, but I haven't figured out how to await
the yielded executor function, which means it will create a race condition if I'm relying on a decorated function to update some value used by any of my other async functions.
Answered By - Rob Truxal
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.