From 6006267d256254d3bb16cb8079c8b4eba1b88746 Mon Sep 17 00:00:00 2001 From: wjqserver <114663932+WJQSERVER@users.noreply.github.com> Date: Wed, 22 Apr 2026 09:00:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Done()=20=E4=BD=BF=E7=94=A8=20sync.Once?= =?UTF-8?q?=20=E7=BC=93=E5=AD=98=20channel=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E5=88=9B=E5=BB=BA=20orDone=20goroutine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复 Gemini 审查意见:多次调用 Done() 时不再重复创建 goroutine, 每个 mergedContext 最多产生 2 个 orDone goroutine。 Alina Agent生成 --- mergectx.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mergectx.go b/mergectx.go index 2e36c09..9aab5bb 100644 --- a/mergectx.go +++ b/mergectx.go @@ -20,6 +20,9 @@ type mergedContext struct { cancelCtx context.Context // deadlineCtx 仅在有 deadline 时非 nil, 用于检测 deadline 到期. deadlineCtx context.Context + // done 缓存 Done() 的 channel, 避免重复创建 orDone goroutine. + done <-chan struct{} + doneOnce sync.Once } // MergeCtx 创建并返回一个新的 context.Context. @@ -135,7 +138,10 @@ func (mc *mergedContext) Deadline() (deadline time.Time, ok bool) { // Done 实现了 context.Context 的 Done 方法. func (mc *mergedContext) Done() <-chan struct{} { if mc.deadlineCtx != nil { - return orDone(mc.cancelCtx, mc.deadlineCtx) + mc.doneOnce.Do(func() { + mc.done = orDone(mc.cancelCtx, mc.deadlineCtx) + }) + return mc.done } return mc.cancelCtx.Done() }