Cancellation Propagation

Cancellation Propagation 是将用户取消信号从 React 前端传播到 Go 后端再到 Python AI Service 的完整机制,确保取消操作能停止整个链路。

#type / concept #status / evergreen #tech / backend #tech / architecture

[!info] related notes

Cancellation Propagation

一句话定义

Cancellation Propagation 是将用户取消信号从 React 前端传播到 Go 后端再到 Python AI Service 的完整机制。取消不只是前端断开连接,而是要确保整个链路都停止工作。

核心原理

取消传播链路

React: AbortController.abort()

    ▼ (HTTP 连接关闭)
Go: r.Context().Done() 触发

    ▼ (调用 AI Service 的 cancel API)
Python: cancel_event.set() → Agent Loop 检测到 → 停止执行

Go 后端的取消感知

func (h *ChatHandler) HandleChat(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()

    // 启动 AI Service 调用
    aiCtx, aiCancel := context.WithCancel(ctx)
    defer aiCancel()

    go func() {
        // 当前端断开连接时,ctx 被 cancel
        <-ctx.Done()
        // 通知 AI Service 停止
        h.aiService.CancelRun(aiCtx, runID)
    }()

    stream, _ := h.aiService.Chat(aiCtx, request)
    for event := range stream {
        select {
        case <-ctx.Done():
            return // 前端已断开
        default:
            writeSSE(w, event)
        }
    }
}

Python AI Service 的取消检测

async def agent_run(context, cancel_event: asyncio.Event):
    async for event in engine.run(context):
        # 每个事件前检查取消信号
        if cancel_event.is_set():
            # 保存已生成内容
            save_partial_result(context.run_id)
            yield DoneEvent(status="cancelled")
            return
        yield event

常见坑

  1. 只断前端连接: Go 后端和 Python 继续执行
  2. 不保存已生成内容: 取消后丢失所有进展
  3. 不做超时: 取消信号传播不到,需要超时兜底
  4. 工具执行不可取消: 正在执行的数据库查询无法中断

参考资料

创建于 2026/6/30 更新于 2026/7/15