filesystem_spec
filesystem_spec copied to clipboard
Asyncio.get_event_loop does not work with fsspec.asyn.sync
Hello, the example below does not work, while I believe it should work.
import asyncio
import fsspec.asyn
print("yey")
loop = asyncio.get_event_loop()
fsspec.asyn.sync(loop, asyncio.sleep, delay=5)
print("yey")
After printing out the first "yey" the program does not output anything, and when it is stopped, it outputs this:
yey
Traceback (most recent call last):
File "F:\SecondaryDownloads\git_repos\gradio\dev_mode.py", line 7, in <module>
print("yey")
File "F:\SecondaryDownloads\git_repos\gradio\venv\lib\site-packages\fsspec\asyn.py", line 54, in sync
if event.wait(1):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2800.0_x64__qbz5n2kfra8p0\lib\threading.py", line 574, in wait
signaled = self._cond.wait(timeout)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2800.0_x64__qbz5n2kfra8p0\lib\threading.py", line 316, in wait
gotit = waiter.acquire(True, timeout)
KeyboardInterrupt
However, it works perfectly when fsspec.asyn.get_loop is used.
import asyncio
import fsspec.asyn
print("yey")
loop = fsspec.asyn.get_loop()
fsspec.asyn.sync(loop, asyncio.sleep, delay=5)
print("yey")
I am unsure why it does not raise an error, and waits indefinitely. It should raise an error according to this line
You are not calling sync from within a loop, you are calling sync with a loop in the same thread, and then blocking waiting on a thread event to be set. The event wait and the event loop cannot progress at the same time, so you deadlock.
Then what about this situation, is it still not from a loop?
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def main():
import asyncio
import fsspec.asyn
print("yey")
print(asyncio.get_running_loop())
loop = asyncio.get_event_loop()
fsspec.asyn.sync(loop, asyncio.sleep, delay=5)
print("yey")

Ah, well if you are in a loop already, you should not be using sync at all. All async backends offer async versions of their methods, and you would simply await them.
Ah, well if you are in a loop already, you should not be using sync at all. All async backends offer async versions of their methods, and you would simply
awaitthem.
Well, this is actually a use-case that is missing in python. For example in Gradio we allow users to launch the server in sync functions for ease of use, and later need async calls.
asyncio.get_event_loop() is being made an alias of asyncio.get_running_loop() on python 3.12