简体   繁体   English

使用异步关闭 Python 中的连接

[英]Closing a connection in Python with asyncio

I am trying to retrieve data from a database for use in an api context.我正在尝试从数据库中检索数据以在 api 上下文中使用。 However I noticed that conn.close() was taking a relatively long time to execute (in this context conn is a connection from a mysql connection pool).但是我注意到 conn.close() 执行时间相对较长(在这种情况下,conn 是来自 mysql 连接池的连接)。 Since closing the connection is not blocking the api's ability to return data I figured I would use asyncio to close the connection async so it wouldn't block the data being returned.由于关闭连接不会阻止 api 返回数据的能力,我想我会使用 asyncio 异步关闭连接,这样它就不会阻止返回的数据。

async def get_data(stuff):
    conn = api.db.get_connection()
    cursor = conn.cursor(dictionary=True)
    data = execute_query(stuff, conn, cursor)
    cursor.close()
    asyncio.ensure_future(close_conn(conn))
    return helper_rows

async def close_conn(conn):
    conn.close()

results = asyncio.run(get_data(stuff))

However despite the fact the asyncio.ensure_future(close(conn)) is not blocking (I put timing statements in to see how long everything was taking and the ones before and after this command were about 1ms different) the actual result won't be gotten until close_conn is completed.然而,尽管事实上 asyncio.ensure_future(close(conn)) 并没有阻塞(我放入计时语句以查看所有内容花费了多长时间,并且该命令之前和之后的那些大约 1ms 不同)实际结果不会是直到 close_conn 完成。 (I verified this using time statements and the difference in time between when it reaches the return statement in get_data and when the line after results=asyncio.run(get_data(stuff)) is about 200ms). (我使用时间语句验证了这一点,以及它到达 get_data 中的 return 语句与 results=asyncio.run(get_data(stuff)) 之后的行之间的时间差约为 200 毫秒)。

So my question is how do I make this code close the connection in the background so I am free to go ahead and process the data without having to wait for it.所以我的问题是如何让这段代码在后台关闭连接,这样我就可以自由地提前 go 并处理数据而无需等待。

Since conn.close() is not a coroutine it blocks the event loop when close_conn is scheduled.由于conn.close()不是协程,它会在close_conn被调度时阻塞事件循环。 If you want to do what you described, use an async sql client and do await conn.close() .如果您想做您所描述的,请使用异步 sql 客户端并执行await conn.close()

You could try using an asynchronous context manager.您可以尝试使用异步上下文管理器。 (async with statement) (与语句异步)

async def get_data(stuff):
    async with api.db.get_connection() as conn:
        cursor = conn.cursor(dictionary=True)
        data = execute_query(stuff, conn, cursor)
        cursor.close()
        asyncio.ensure_future(close_conn(conn))
        return helper_rows

results = asyncio.run(get_data(stuff))

If that doesn't work the sql client you are using try with aiosqlite.如果这不起作用,请尝试使用 aiosqlite 的 sql 客户端。

https://github.com/omnilib/aiosqlite https://github.com/omnilib/aiosqlite

import aiosqlite

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM