Files
inquiry_robot/inquiry-agent/agent/jobs/wake_consumer.py
T

83 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Worker 侧:消费主账/文件完成等结构化 wake。
本文件职责:Redis Stream 入队/认领;在 HTTP 类槽内调 GraphRuntime.wake_from_worker。
禁止:在企微回调线程调用;禁止用户文字冒充本路径。
"""
from __future__ import annotations
import logging
from typing import Any, Optional
from agent.graph.runtime import GraphRuntime
from agent.graph.wake import WorkerWakePayload
from agent.redis_coord.client import RedisClient
from agent.redis_coord.stream_queue import StreamQueue
logger = logging.getLogger(__name__)
STREAM_WAKE = "stream:wake"
WAKE_GROUP = "inquiry-wake-workers"
def wake_stream(client: RedisClient) -> StreamQueue:
"""结构化 wake 专用 Stream。"""
q = StreamQueue(client=client, stream_suffix=STREAM_WAKE, group=WAKE_GROUP)
q.ensure_group()
return q
def enqueue_wake(client: RedisClient, payload: WorkerWakePayload) -> str:
"""
入队 wake(HTTP bridge 快回路径)。
副作用:XADD;不跑 Graph。
"""
payload.validate()
q = wake_stream(client)
return q.enqueue(
payload={
"thread_id": payload.thread_id,
"inquiry_no": payload.inquiry_no,
"quote_version": int(payload.quote_version),
"wait_version": int(payload.wait_version),
"kind": payload.kind,
"detail": payload.detail or {},
},
idempotency_key=f"wake:{payload.thread_id}:{payload.wait_version}:{payload.kind}",
)
def claim_and_apply_wake(
*,
queue: StreamQueue,
graph: GraphRuntime,
consumer: str,
) -> bool:
"""
认领 1 条并 wake Graph。成功/失败均 ack(骨架防堵死;正式应进死信)。
返回:是否领到任务。
"""
claimed = queue.claim(consumer=consumer, count=1, block_ms=200)
if not claimed:
return False
entry_id, data = claimed[0]
try:
wake = WorkerWakePayload(
thread_id=str(data.get("thread_id") or ""),
inquiry_no=str(data.get("inquiry_no") or ""),
quote_version=int(data.get("quote_version") or 0),
wait_version=int(data.get("wait_version") or 0),
kind=str(data.get("kind") or ""),
detail=dict(data.get("detail") or {}),
)
graph.wake_from_worker(wake)
logger.info("wake 已处理 id=%s thread=%s kind=%s", entry_id, wake.thread_id, wake.kind)
except Exception: # noqa: BLE001
logger.exception("wake 处理失败 id=%s", entry_id)
finally:
queue.ack(entry_id)
return True