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

如何在Trio/Anyio中暂停任务并更新Cookie后恢复执行?

在Trio/Anyio中实现任务全局暂停与恢复(Cookie更新场景)

完全可以实现这类需求,核心思路是通过共享同步原语控制任务的暂停/恢复,同时保证Cookie更新操作仅执行一次。以下是针对Trio和Anyio的具体实现方案:

Trio 实现方案

利用Trio内置的Lock(保证更新操作互斥)和Event(控制任务启停),可以轻松实现全局任务暂停与Cookie更新的逻辑:

import trio

# 全局状态管理
current_cookies = None
cookie_is_valid = False
# 确保Cookie更新操作仅执行一次
update_lock = trio.Lock()
# 控制任务运行状态:初始为允许运行(事件已设置)
resume_event = trio.Event()
resume_event.set()

async def get_cookies():
    # 模拟实际获取/刷新Cookie的逻辑
    await trio.sleep(1)
    return {"session_id": f"valid_session_{trio.current_time():.0f}"}

async def crawler_task(task_id):
    global current_cookies, cookie_is_valid
    while True:
        # 等待恢复信号:若处于暂停状态,此处会阻塞
        await resume_event.wait()
        
        # 检查Cookie有效性,无效则触发更新流程
        if not cookie_is_valid:
            async with update_lock:
                # 双重检查,避免重复更新
                if not cookie_is_valid:
                    # 暂停所有任务:清除事件,后续任务会阻塞在wait()
                    resume_event.clear()
                    print(f"任务{task_id}发现Cookie过期,启动更新流程")
                    current_cookies = await get_cookies()
                    cookie_is_valid = True
                    # 恢复所有任务:设置事件,所有阻塞任务继续执行
                    resume_event.set()
                    print(f"任务{task_id}完成Cookie更新,恢复全局任务")
        
        # 模拟爬虫业务逻辑
        print(f"任务{task_id}使用Cookie {current_cookies}执行爬取")
        await trio.sleep(2)
        
        # 模拟Cookie过期触发(实际场景可替换为请求返回的过期判断)
        if task_id == 1 and trio.current_time() % 10 < 2:
            cookie_is_valid = False
            print(f"任务{task_id}检测到Cookie过期")

async def main():
    # 初始化Cookie
    global current_cookies, cookie_is_valid
    current_cookies = await get_cookies()
    cookie_is_valid = True
    print("初始Cookie已成功获取")
    
    # 启动多爬虫任务
    async with trio.Nursery() as nursery:
        for i in range(3):
            nursery.start_soon(crawler_task, i+1)

if __name__ == "__main__":
    trio.run(main)

Anyio 实现方案

Anyio兼容Trio和asyncio后端,只需将同步原语替换为Anyio的API,逻辑与Trio完全一致:

import anyio

# 全局状态管理
current_cookies = None
cookie_is_valid = False
update_lock = anyio.Lock()
resume_event = anyio.Event()
resume_event.set()

async def get_cookies():
    await anyio.sleep(1)
    return {"session_id": f"valid_session_{anyio.current_time():.0f}"}

async def crawler_task(task_id):
    global current_cookies, cookie_is_valid
    while True:
        await resume_event.wait()
        
        if not cookie_is_valid:
            async with update_lock:
                if not cookie_is_valid:
                    resume_event.clear()
                    print(f"任务{task_id}发现Cookie过期,启动更新流程")
                    current_cookies = await get_cookies()
                    cookie_is_valid = True
                    resume_event.set()
                    print(f"任务{task_id}完成Cookie更新,恢复全局任务")
        
        print(f"任务{task_id}使用Cookie {current_cookies}执行爬取")
        await anyio.sleep(2)
        
        # 模拟Cookie过期触发
        if task_id == 2 and anyio.current_time() % 10 < 2:
            cookie_is_valid = False
            print(f"任务{task_id}检测到Cookie过期")

async def main():
    global current_cookies, cookie_is_valid
    current_cookies = await get_cookies()
    cookie_is_valid = True
    print("初始Cookie已成功获取")
    
    async with anyio.create_task_group() as tg:
        for i in range(3):
            tg.start_soon(crawler_task, i+1)

if __name__ == "__main__":
    anyio.run(main)

关键实现要点

  • 互斥锁(Lock):确保Cookie更新操作仅由一个任务执行,避免重复请求更新
  • 事件(Event):实现全局任务的暂停/恢复,任务每次执行前会等待事件触发
  • 双重检查有效性:在获取锁后再次确认Cookie状态,防止等待锁期间其他任务已完成更新

内容的提问来源于stack exchange,提问作者αԋɱҽԃ αмєяιcαη

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:25:19