You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Recently, I've been playing with BackgroundTasks through DI in a FastAPI app.
The app itself has a simple GET request endpoint that proxies requests to a third-party API. It also uses aioredis for caching, thus in case of a cache miss it makes a real request and puts a response into Redis. I've decided to make response caching in the background, so my code looked like this:
This works perfectly fine functionality-wise, but sometimes it spits these logs:
/...venvpath/lib/python3.7/site-packages/uvicorn/main.py:307: RuntimeWarning: coroutine 'wait_ok' was never awaited
loop.run_until_complete(self.serve(sockets=sockets))
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
I was looking for the wait_ok in the libraries I'm using and finally came across it in aioredis. Except the mentioned before aioredis.command.Redis.set (which is always added into the BackgroundTasks in my code) I'm using only aioredis.command.Redis.get method, and I've made sure every single call is being awaited.
Next, I've started looking through the BackgroundTasks code and found this line:
I've managed to figure out the issue: aioredis.command.Redis.set itself is not an async function, but it seems to rather return one through a wild chain of function calls. I didn't bother to untangle it, not sure if it's even necessary.
Now, the thing is the current Starlette's documentation doesn't tell anything about the callable BackgroundTask wraps. Maybe, it should be updated telling a user they can wrap both sync and async functions and warn against these kind of cases such as mine?
This discussion was converted from issue #769 on February 14, 2022 10:24.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Recently, I've been playing with
BackgroundTasks
through DI in a FastAPI app.The app itself has a simple GET request endpoint that proxies requests to a third-party API. It also uses aioredis for caching, thus in case of a cache miss it makes a real request and puts a response into Redis. I've decided to make response caching in the background, so my code looked like this:
This works perfectly fine functionality-wise, but sometimes it spits these logs:
I was looking for the
wait_ok
in the libraries I'm using and finally came across it in aioredis. Except the mentioned beforeaioredis.command.Redis.set
(which is always added into theBackgroundTasks
in my code) I'm using onlyaioredis.command.Redis.get
method, and I've made sure every single call is being awaited.Next, I've started looking through the
BackgroundTasks
code and found this line:starlette/starlette/background.py
Line 14 in 06d0fc4
I've managed to figure out the issue:
aioredis.command.Redis.set
itself is not an async function, but it seems to rather return one through a wild chain of function calls. I didn't bother to untangle it, not sure if it's even necessary.Finally, I've changed my code a little bit:
And it seemed to do the trick (I hope 👀 ).
Now, the thing is the current Starlette's documentation doesn't tell anything about the callable
BackgroundTask
wraps. Maybe, it should be updated telling a user they can wrap both sync and async functions and warn against these kind of cases such as mine?Beta Was this translation helpful? Give feedback.
All reactions