Connections not closing when async tasks are cancelled
PartlyAtomic opened this issue · comments
Description
When a task is cancelled while an aiosqlite.Connection object is connecting, the sqlite connection is never closed and is left hanging. Additionally the aiosqlite.Connection threads don't get shut down.
Details
- OS: Windows 10 Pro 10.0.19045
- Python version: 3.11.5
- aiosqlite version: 0.19.0
- Can you repro on 'main' branch? Yes
- Can you repro in a clean virtualenv? Yes
Repro code:
import asyncio
import aiosqlite
async def connect_to_db():
async with aiosqlite.connect("test.db") as db:
await db.execute("SELECT value FROM generate_series(0,1000000,1)")
async def main_loop():
tasks = []
for i in range(5):
tasks.append(asyncio.create_task(connect_to_db()))
print("Tasks started")
await asyncio.sleep(0)
print("Async tick")
for task in tasks:
task.cancel()
print("Tasks cancelled")
for task in tasks:
try:
await task
except asyncio.CancelledError:
continue
# This was a debug helper to track open connections
# from aiosqlite.core import print_connections_info
# print_connections_info()
await asyncio.sleep(5)
print("Complete")
if __name__ == "__main__":
asyncio.run(main_loop())
Expected behavior: File handles for test.db would be released as tasks were successfully cancelled.
Actual behavior: 5 file handles are kept indefinitely for test.db (can be verified with a program such as OpenedFilesView or keeping track of the sqlite connections). Additionally after the event loop stops, the script hangs.
I suspect there may be other problems when tasks are cancelled, but haven't figured out minimal test cases for them yet. My program was often getting into a state where a series of cancelled write tasks would eventually lock the database indefinitely.