Closed maretodoric closed 5 months ago
Well. Maybe, how would i know?
Looking at the doc:
some extension modules, either standard or third-party, are designed so as to release the GIL when doing computationally intensive tasks such as compression or hashing. Also, the GIL is always released when doing I/O.
And I'm doing multiple i/o tasks at the time of block (reading from mssql db into pandas dataframe using pandas.read_sql).
Could this be worked around, no?
A relatively straightforward way to tell is:
async def count():
for i in range(1_000_000):
print(i)
await asyncio.sleep(0.1)
loop.create_task(count())
pandas.read_sql
) via run_in_executor
async def will_it_block():
await asyncio.sleep(1) # check that count() started
print("will it block?")
await loop.run_in_executor(None, blocking_function, bf_arg)
loop.create_task(will_it_block())
If count()
stops counting, then it's purely a pandas / asyncio problem — nothing that I can fix at the level of websockets.
Ok, good point. I've implemented that test and it seems it runs fine - i can see counter running together with blocking task. However, I should've also pointed out that i have few background tasks created with asyncio.create_task that are also running while blocking operation is running, but websocket still stops receiving any data (pings and other messages included) while the blocking operation is ongoing..
As for test you proposed, i did a slight variation, like this:
loop.create_task(count()) # count() function is like the one you wrote
await asyncio.sleep(1) # check that count() started
res = await loop.run_in_executor(None, (lambda payload, tunnel: Action(payload,tunnel).call_action()), payload, tunnel)
print("blocking function completed")
return res
So i did not create two tasks.
I have to point out, however, that at some point counter stopped counting. I've then adjusted pandas chunksize and after that, counter did not stop at any point, so it appears that it blocks at the time when pandas is assembling a large dataframe.
Currently, it appears to work, thanks! I did not know about GIL before you mentioned it. Now i can find a way to work around it when needed for some future purpose.
If I understand correctly, the problem was that you were blocking the event loop due to a chunksize too large, blocking the entire Python process (incl. the event loop).
On the side of websockets, you can also adjust ping_timeout
if the default of 20 seconds isn't enough.
This is continuation of issue #1298 , I'm facing the same problem as described in that thread however I'm calling blocking functions properly (or at least, i should be). I cannot reopen that thread as I'm not the original author so I'm opening new thread.
When i have blocking code, I'm running it with asyncio.to_thread. I've also attempted to run it with:
And every time when it's running a long time - it blocks. Client cannot receive new messages and keepalive pings are not sent/received.
Using websockets 2.0.
If it means anything, this websockets client is running on Windows.