Files
q792602257 48c6f2a28f feat(gateway): 下单任务支持 callback_url 终结类事件异步通知
- POST /api/orders 新增可选 callback_url(仅 http/https,其余 422)
- 仅终结类事件各通知一次:terminal report 推入终态(succeeded/failed/
  needs_human)、租约过期被 sweep 置 stale;中间态与终结后的监控上报不通知
- 幂等重发不更新既有任务的回调地址;投递 best-effort 单次尝试,失败只记日志
- CallbackNotifier 发后不管(create_task + 在途任务强引用),关停等在途发完;
  生产路径按回调地址逐次构造客户端,满足统一出站代理策略(test_proxy.py)
- tasks 表加 callback_url 列,GatewayDB.start() 内置迁移兼容既有库
- 新增 RAKUTEN_CALLBACK_TIMEOUT_SECONDS(默认 10);文档补 §4.8;
  openapi.json 重新导出(gitignore 未跟踪);新增 17 条测试,全量 492 通过
2026-08-17 01:05:37 +08:00

45 lines
1.9 KiB
Python

"""网关容器:集中管理网关侧服务实例,用于依赖注入"""
from __future__ import annotations
import asyncio
import logging
from dataclasses import dataclass, field
from app.gateway.db import GatewayDB
from app.gateway.query_queue import QueryQueue
from app.gateway.task_queue import TaskQueue
from app.shared.config import Settings
logger = logging.getLogger(__name__)
@dataclass(slots=True)
class GatewayContainer:
"""网关容器
与抓取/交易容器同样的依赖注入风格,但持有的是任务队列与 SQLite 连接,
生命周期由 main.lifespan 管理:start 时打开 DB,close 时关闭。
两条通道各有一个队列对象,共用同一个 GatewayDB:
- `task_queue` 下单任务(不可逆写,租约过期只置 stale)
- `query_queue` 账号只读查询(可安全重投,见 query_queue.py 顶部对照表)
`sweep_task` 是常驻后台扫描,把过期的 leased/running 推到 stale,并顺带扫
一轮查询单(重投 / 过期 / 清理过保留期的结果)。即使没有 lease 请求,过期的
任务也会被及时发现(规格 §5 的关键约束)。
`collector` 是定时下派通道(§12):周期性派 order_list / order_detail 查询、
把账户真实订单沉淀进 `account_orders` 编目。`collector_task` 是它的后台任务,
在 lifespan 里与 `sweep_task` 一起启动/取消。
"""
settings: Settings
db: GatewayDB
task_queue: TaskQueue
query_queue: QueryQueue
collector: object | None = field(default=None) # app.gateway.collector.OrderDiscoveryCollector
# 终结类事件回调(§4.8):有 callback_url 的任务到达终态/变 stale 时 POST 通知上游
notifier: object | None = field(default=None) # app.gateway.callback.CallbackNotifier
sweep_task: asyncio.Task | None = None
collector_task: asyncio.Task | None = None