asyncmy icon indicating copy to clipboard operation
asyncmy copied to clipboard

当请求被取消的时候,任务被CancelledError,但是连接没有被正确回收

Open flyoverGu opened this issue 1 year ago • 3 comments

Traceback (most recent call last):
  File "/home/ubuntu/work/friday-py/venv/lib/python3.10/site-packages/tortoise/transactions.py", line 57, in wrapped
    return await func(*args, **kwargs)
  File "/home/ubuntu/work/friday-py/router.py", line 162, in msg_sec_check
    dc_res = await Danmu_cache.filter(md5=md5).first()
  File "/home/ubuntu/work/friday-py/venv/lib/python3.10/site-packages/tortoise/queryset.py", line 1008, in _execute
    instance_list = await self._db.executor_class(
  File "/home/ubuntu/work/friday-py/venv/lib/python3.10/site-packages/tortoise/backends/base/executor.py", line 131, in execute_select
    _, raw_results = await self.db.execute_query(query.get_sql())
  File "/home/ubuntu/work/friday-py/venv/lib/python3.10/site-packages/tortoise/backends/mysql/client.py", line 44, in translate_exceptions_
    return await func(self, *args)
  File "/home/ubuntu/work/friday-py/venv/lib/python3.10/site-packages/tortoise/backends/mysql/client.py", line 199, in execute_query
    await cursor.execute(query, values)
  File "asyncmy/cursors.pyx", line 179, in execute
  File "asyncmy/cursors.pyx", line 364, in _query
  File "asyncmy/connection.pyx", line 494, in query
  File "asyncmy/connection.pyx", line 682, in _read_query_result
  File "asyncmy/connection.pyx", line 1069, in read
  File "asyncmy/connection.pyx", line 617, in read_packet
  File "asyncmy/connection.pyx", line 656, in _read_bytes
  File "/usr/lib/python3.10/asyncio/streams.py", line 708, in readexactly
    await self._wait_for_data('readexactly')
  File "/usr/lib/python3.10/asyncio/streams.py", line 501, in _wait_for_data
    await self._waiter
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "handle_request", line 102, in handle_request
    try:
  File "/home/ubuntu/work/friday-py/venv/lib/python3.10/site-packages/tortoise/transactions.py", line 56, in wrapped
    async with in_transaction(connection_name):
  File "/home/ubuntu/work/friday-py/venv/lib/python3.10/site-packages/tortoise/backends/base/client.py", line 279, in __aexit__
    await self.connection.rollback()
  File "/home/ubuntu/work/friday-py/venv/lib/python3.10/site-packages/tortoise/backends/mysql/client.py", line 255, in rollback
    await self._connection.rollback()
  File "asyncmy/connection.pyx", line 412, in rollback
  File "asyncmy/connection.pyx", line 377, in _read_ok_packet
asyncmy.errors.OperationalError: (2014, 'Command Out of Sync')

使用sanic,当请求正在处理 await self._waiter 的时候,客服端主动取消请求,这个时候 self._connection.rollback() 会失败,数据库连接一直没办法被回收。

flyoverGu avatar Jul 19 '24 08:07 flyoverGu

是的,我也遇到了这个问题,我是使用sanic框架,并且使用了tortoise-orm==0.19.1,它默认优先使用asyncmy包,导致当客户端取消请求时,连接紊乱,当前的请求sql,拿到的是上个接口的sql查询结果,然后tortoise拿到数据去做映射,结果报keyerror Traceback (most recent call last): File "handle_request", line 83, in handle_request class Sanic(BaseSanic, metaclass=TouchUpMeta): File "/app/handler/ad_operation.py", line 180, in get_ad_config ad_config = await AdConfigService.get_ad_content_by_pkg_and_group_and_lang(pkg, group, lang, is_new_user) File "/app/bll/ad_operation.py", line 73, in get_ad_content_by_pkg_and_group_and_lang ).values("ad_content") File "/usr/local/lib/python3.7/site-packages/tortoise/queryset.py", line 1623, in _execute row[col] = func(row[col]) KeyError: 'ad_content' tortoise的导入包源码如下: import asyncio from functools import wraps from typing import Any, Callable, List, Optional, SupportsInt, Tuple, TypeVar, Union

try: import asyncmy as mysql from asyncmy import errors from asyncmy.charset import charset_by_name except ImportError: import aiomysql as mysql from pymysql.charset import charset_by_name from pymysql import err as errors

bs-101 avatar Sep 23 '24 05:09 bs-101

是的,我也遇到了这个问题,我是使用sanic框架,并且使用了tortoise-orm==0.19.1,它默认优先使用asyncmy包,导致当客户端取消请求时,连接紊乱,当前的请求sql,拿到的是上个接口的sql查询结果,然后tortoise拿到数据去做映射,结果报keyerror Traceback (most recent call last): File "handle_request", line 83, in handle_request class Sanic(BaseSanic, metaclass=TouchUpMeta): File "/app/handler/ad_operation.py", line 180, in get_ad_config ad_config = await AdConfigService.get_ad_content_by_pkg_and_group_and_lang(pkg, group, lang, is_new_user) File "/app/bll/ad_operation.py", line 73, in get_ad_content_by_pkg_and_group_and_lang ).values("ad_content") File "/usr/local/lib/python3.7/site-packages/tortoise/queryset.py", line 1623, in _execute row[col] = func(row[col]) KeyError: 'ad_content' tortoise的导入包源码如下: import asyncio from functools import wraps from typing import Any, Callable, List, Optional, SupportsInt, Tuple, TypeVar, Union

try: import asyncmy as mysql from asyncmy import errors from asyncmy.charset import charset_by_name except ImportError: import aiomysql as mysql from pymysql.charset import charset_by_name from pymysql import err as errors

同样的问题。被困扰了很久。 打算切换到aiomysql了。

canghai118 avatar Nov 05 '24 03:11 canghai118

@canghai118 可以试下在nginx上 新增 proxy_ignore_client_abort on; 就算客户端取消请求,nginx 不直接取消请求,让请求执行完成。

flyoverGu avatar Nov 05 '24 06:11 flyoverGu