背景:我正在利用自定義 LDAP 服務器包。它使用Done請求中的通道讓處理程序知道是否(例如客戶端斷開連接),因此處理程序也應該中止。由于Done通道是處理取消的舊方法 - 并且我希望支持取消鏈接 - 我context.Context從這個通道創(chuàng)建了一個,如下所示: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通道將關閉:客戶端斷開連接;和成功的處理程序(完全運行完成)第一個事實證明是正確的,而第二個事實則不然。成功的處理程序調用不會觸發(fā)通道done關閉 - 因此我泄漏了 go-routines。為了解決這個問題 - 由于我context.Context在處理程序完成時取消了自己的操作 - 成功與否,例如// convert the client request's Done channel into a context.Contextctx, 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)? ? ? ? }}()問題:這是將舊式done頻道升級為更現(xiàn)代頻道的正確方法嗎context.Context我應該擔心我正在使用的外部包沒有關閉通道嗎done?即會GC收集該通道,即使它從未關閉?
- 1 回答
- 0 關注
- 122 瀏覽
添加回答
舉報
0/150
提交
取消