从完成通道和未关闭通道的 GC 中生成 context.Context

generate context.Context from Done channel & GC of unclosed channels

背景:

我正在利用自定义 LDAP 服务器 package. It uses a Done channel within requests to let the handler know if - say the client disconnects - and thus the handler should abort also. For example

由于 Done 通道是处理取消的旧方法 - 我希望支持取消链接 - 我从这个通道创建了一个 context.Context ,如下所示:

func doneContext(p context.Context, done <-chan bool) (
    ctx context.Context, cancel context.CancelFunc,
) {
    ctx, cancel = context.WithCancel(p)
    go func() {
            <-done
            cancel() // done closed, so cancel our context
    }()
    return
}

这假设 done 通道将关闭:

第一个被证明是正确的 - 第二个没有。成功的处理程序调用将 不会 触发 done 通道关闭 - 因此我正在泄漏 go-routines。


解决这个问题 - 因为我在处理程序完成时取消了我自己的 context.Context - 成功与否,例如

// convert the client request's Done channel into a context.Context
ctx, cancel := doneContext(context.Background(), m.Done)
defer cancel() // clean-up context: rain or shine

我像这样更新了 doneContext 的 go 例程:

go func() {
        select {
        case <-done:
            cancel() // done closed, so cancel our context (like before)

        case <-ctx.Done():
            // when our context is canceled, recover the go-routine (even if done never closes)
        }
}()

问题:

您不需要关闭频道。如果没有任何内容引用频道,它将被垃圾收集。

您的频道逻辑似乎是正确的。