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

是否可直接将Future状态存储在Application对象上?

能否直接将Future的状态存储在Application对象上?

嘿,这个问题我刚好有实际项目经验可以分享——答案是完全可以这么做,但在实际落地时得留意几个关键细节,不然容易踩坑:

1. 避免重复创建已完成的任务

你的示例代码里用getattr(app, 'task_obj', None)来判断任务是否存在,这个思路没问题,但有个小漏洞:当任务正常跑完或者被取消后,task_obj还会留在app对象上,只是它的状态变成了done()。这时候后续请求进来会直接复用这个已经结束的Future,根本不会执行新的后台逻辑。

所以判断的时候,得加上任务是否活跃的检查:

if task is None or task.done():
    # 只有任务不存在或者已经结束时,才创建新任务
    task = asyncio.create_task(background())  # Python3.7+推荐用create_task替代ensure_future
    callback = partial(done_refresh, app)
    task.add_done_callback(callback)
    app.task_obj = task

另外还要考虑并发竞态问题:如果多个请求同时进来,刚好都检测到task_obj是None,就会重复创建多个后台任务。解决这个问题很简单,给app加个异步锁就行:

# 先在app初始化的时候加个锁
app['task_lock'] = asyncio.Lock()

# 然后在loading视图里用锁包裹判断逻辑
async with app['task_lock']:
    task = getattr(app, 'task_obj', None)
    if task is None or task.done():
        task = asyncio.create_task(background())
        callback = partial(done_refresh, app)
        task.add_done_callback(callback)
        app.task_obj = task

2. 一定要处理任务的异常

如果你的background()任务抛出了异常,默认情况下这个异常不会主动暴露出来——因为后台任务的异常如果没被捕获,只会在任务完成时默默“吃掉”,你根本不知道任务失败了。

所以在done_refresh回调里,一定要主动取出任务的结果,触发异常并处理:

def done_refresh(app, task):
    try:
        task.result()  # 这里会抛出任务执行过程中出现的异常
    except Exception as e:
        print(f"后台任务执行失败: {e}")
        # 可以在这里把app上的task_obj置空,方便后续重新创建任务
        app.task_obj = None

要是不处理这些异常,积累多了可能会影响整个应用的稳定性。

3. 应用关闭时记得清理任务

当aiohttp应用要关闭的时候,得确保后台任务被优雅取消,不然可能会留下僵尸任务或者资源泄漏。可以给app注册一个关闭回调:

async def on_app_shutdown(app):
    task = getattr(app, 'task_obj', None)
    if task and not task.done():
        task.cancel()
        try:
            await task  # 等待任务被取消完成
        except asyncio.CancelledError:
            print("应用关闭时,后台任务已被取消")

# 在初始化app的时候注册这个回调
app.on_shutdown.append(on_app_shutdown)

4. 关于Application对象的本质

其实aiohttp的Application就是一个全局的、和应用生命周期绑定的存储容器,只要你保证对它的访问是协程安全的(比如用刚才说的锁),存Future或者任务对象完全没问题,非常适合存放跨请求共享的后台任务状态。

总的来说,这种做法是可行的,只要把上面这几个细节处理好,就能让后台任务稳定运行~

内容的提问来源于stack exchange,提问作者Most Wanted

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:43:16