- 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 通过
45 lines
1.9 KiB
Python
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
|