Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aiosqlite leaves thread hanging #290

Open
raees-khan opened this issue Apr 5, 2024 · 4 comments
Open

Aiosqlite leaves thread hanging #290

raees-khan opened this issue Apr 5, 2024 · 4 comments

Comments

@raees-khan
Copy link

raees-khan commented Apr 5, 2024

class ProxyClass:
     def __init__(self):
         self._conn = None
         self._connected = False
    
    async def connect(self):
        self._conn = await aiosqlite.connect(':memory:')
        self._connected = True

    def close(self):
        await self._conn.close()
        self._connected = False
   
    def __getattr__(self, name):
        return getattr(self._conn, name)


async def run():
    db = ProxyClass()
    await db.connect()
   try:
        #perform some long running db updates
        #commit changes
   finally:
        await db.close()

I import this in a script and call run using asyncio.run(run()). It finishes but the program never exits because the thread does not get stopped and ctrl+c spits following.

^CException ignored in: <module 'threading' from '/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/threading.py'> Traceback (most recent call last): File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/threading.py", line 1448, in _shutdown lock.acquire() KeyboardInterrupt:

@amyreese
Copy link
Member

amyreese commented Apr 6, 2024

I can’t replicate this with the example code. Are you sure your “long running db updates” have actually completed before pressing ctrl-c? Can you provide more insight on what that long running functionality entails?

@TJAkalit
Copy link

TJAkalit commented Apr 8, 2024

Hello
I have the same problem. But in my case its short select for two rows in result.

@raees-khan
Copy link
Author

I have found that it happens when you have multiple connections (aka multiple threads).

import aiosqlite
import asyncio

class ProxyClass:
    def __init__(self):
        self._conn = None
        self._connected = False
    
    async def connect(self):
        self._conn = await aiosqlite.connect(':memory:')
        self._connected = True

    async def close(self):
        await self._conn.close()
        self._connected = False
   
    def __getattr__(self, name):
        return getattr(self._conn, name)
        

class DBRunner:
	
	def __init__(self):
		self._dbs = {
			"db1": ProxyClass(),
			"db2": ProxyClass()
		}
	
	async def init_dbs(self):
		await asyncio.gather(
			*[db.connect() for db in self._dbs.values()]
		)
	
	async def close_dbs(self):
		for db in self._dbs.values():
			await db.close()
	
	async def run(self, name):
		db = self._dbs[name]
		await db.execute("CREATE TABLE memview_v1 (X, Y)")
		await db.execute("INSERT INTO memview_v1 (X, Y) VALUES(1,2)")
		await db.commit()		
		


async def main():
	runner = DBRunner()
	try:
		await runner.init_dbs()
		await asyncio.gather(*[runner.run(name) for name in ('db1', 'db2')])
	finally:
		await runner.close_dbs()
		
asyncio.run(main())

for each connection a separate thread is created. The actual code makes thousands of inserts updates and deletes to disk based db connection, but I ensure to call db.close() of each db in my finally block. The program never really exits and the shell hangs and ctrl+c yields that output

@waketzheng
Copy link
Contributor

Got hanging by the following code at MacOS with python3.10 and aiosqlite==0.20.0

import asyncio
from contextlib import asynccontextmanager

import aiosqlite


@asynccontextmanager
async def open_db():
    async with aiosqlite.connect("db.sqlite3"):
        yield


@asynccontextmanager
async def nest_open():
    async with open_db():
        yield


async def gen():
    async with nest_open():
        yield


async def main():
    async for _ in gen():
        raise TypeError()


asyncio.run(main())

Related issue #306

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants