You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中httpx.AsyncClient长生命周期引发事件循环关闭问题咨询

问题解答

你的推测是正确的,RuntimeError('Event loop is closed')确实是因为全局的httpx.AsyncClient实例绑定的事件循环被关闭导致的,和asgiref.async_to_sync本身无关。

原因分析

httpx.AsyncClient在创建时会自动绑定到当前线程的事件循环。你通过partial创建的AsyncApi是全局对象,其中的AsyncClient实例会被所有请求复用:

  • Django同步视图中,async_to_sync会为每个请求创建或复用事件循环,当某个请求处理完成后,对应的事件循环可能被关闭;
  • 后续请求复用这个全局AsyncClient时,它引用的是已关闭的旧事件循环,从而触发错误。

解决方案

并不是只能每次请求都实例化httpx.AsyncClient,但这是最稳妥且易于维护的方案。以下是几种可行的处理方式:

1. 每次请求实例化AsyncClient

在视图方法中为每个请求创建独立的AsyncClient实例,确保它绑定到当前请求的事件循环:

class MyViewSet(viewsets.GenericViewSet):
    @action(...)
    def merge(self, request: Request) -> Response:
        # 为当前请求创建新的AsyncClient实例
        async_api = Api(token=request.auth, async_client=httpx.AsyncClient(timeout=30))
        result = async_to_sync(merge_task)(..., api=async_api)
        ...

如果merge_task是异步函数,最好在内部使用async with来自动管理Client生命周期:

async def merge_task(...):
    async with httpx.AsyncClient(timeout=30) as client:
        api = Api(token=..., async_client=client)
        # 执行API调用逻辑
        ...

2. 改用Django异步视图

将视图改为异步模式,直接在异步上下文管理AsyncClient,避免async_to_sync的循环切换问题:

class MyViewSet(viewsets.GenericViewSet):
    @action(... , renderer_classes=[...])
    async def merge(self, request: Request) -> Response:
        async with httpx.AsyncClient(timeout=30) as client:
            api = Api(token=request.auth, async_client=client)
            result = await merge_task(..., api=api)
        return Response(result)

3. 线程本地存储的Client实例

利用线程本地存储为每个请求线程创建独立的AsyncClient,避免跨线程循环冲突:

import threading
from functools import partial

thread_local = threading.local()

def get_thread_local_client():
    if not hasattr(thread_local, "async_client"):
        thread_local.async_client = httpx.AsyncClient(timeout=30)
    return thread_local.async_client

AsyncApi = partial(Api, async_client=get_thread_local_client())

注意:这种方式需要通过Django中间件在请求结束后清理Client,避免资源泄漏。

总结

优先选择每次请求实例化AsyncClient或改用异步视图的方案,这两种方式能最大程度避免事件循环相关的错误,同时代码逻辑清晰、易于维护。

内容的提问来源于stack exchange,提问作者Murilo Sitonio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:26:18