go resource_error ai_generated true

错误: 上下文截止时间已过(取消后 goroutine 阻塞在 <-ch)

error: context deadline exceeded (goroutine blocked on <-ch after cancel)

ID: go/goroutine-leak-on-ctx-cancel

其他格式: JSON · Markdown 中文 · English
80%修复率
87%置信度
0证据数
2024-08-09首次发现

版本兼容性

版本状态引入弃用备注
1.18 active — — —
1.20 active — — —
1.21 active — — —
1.22 active — — —

根因分析

goroutine 等待一个仅在成功时写入的 channel。ctx 取消后发送者提前返回从不发送,接收者永远阻塞。

English

A goroutine waits on a channel that is only written on success. When ctx is cancelled the sender returns early and never sends, leaving the receiver blocked forever.

generic

解决方案

  1. 95% 成功率
    Select on ctx.Done() alongside the channel:
    
    select {
    case v := <-ch:
        return v, nil
    case <-ctx.Done():
        return nil, ctx.Err()
    }
  2. 90% 成功率
    Ensure producers always send or close on exit:
    
    defer close(ch)
    for _, item := range items {
        select {
        case ch <- item:
        case <-ctx.Done():
            return
        }
    }

无效尝试

常见但无效的做法:

  1. 70% 失败

    Delays the leak; cancel still leaves the receiver blocked.

  2. 65% 失败

    default makes the loop spin hot and still does not deliver the value.