更新 1:似乎使用綁定到 HTTP 請求的上下文可能會導致“上下文取消”錯誤。但是,使用 context.Background() 作為父母似乎工作正常。 // This works, no 'context canceled' errors ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second) // However, this creates 'context canceled' errors under mild load // ctx, cancel := context.WithTimeout(r.Context(), 100*time.Second) defer cancel() app.Insert(ctx, record)(更新了下面的代碼示例以生成一個獨立的重現示例)在 go 中,我有一個類似于以下代碼的 http 處理程序。在對該端點的第一個 HTTP 請求中,我收到一個context cancelled錯誤。但是,數據實際上是插入到數據庫中的。在對該端點的后續請求中,不會出現此類錯誤,并且數據也已成功插入數據庫。問題:我context是否在 http 處理程序和pgx QueryRow 方法之間正確設置和傳遞?(如果沒有,有更好的方法嗎?)如果將此代碼復制到 main.go 并運行go run main.go,轉到localhost:4444/create并按住ctrl-R以產生輕微的負載,您應該會看到產生了一些上下文取消的錯誤。
1 回答
動漫人物
TA貢獻1815條經驗 獲得超10個贊
TLDR:r.Context()在生產中使用效果很好,使用瀏覽器進行測試是個問題。
一個 HTTP 請求獲得它自己的上下文,當請求完成時該上下文被取消。這是一個特性,而不是一個錯誤。當請求被客戶端中斷或超時時,開發人員應該使用它并優雅地關閉執行。例如,取消的請求可能意味著客戶端永遠不會看到響應(交易結果),開發人員可以決定回滾該交易。
在生產中,對于正常設計/構建的 API,請求取消不會經常發生。通常,流程由服務器控制,服務器在取消請求之前返回結果。多個Client請求不會互相影響,因為他們得到獨立的go-routine和context。同樣,我們正在談論正常設計/構建應用程序的快樂路徑。您的示例應用程序看起來不錯,應該可以正常工作。
問題是我們如何測試應用程序。我們使用瀏覽器并刷新單個瀏覽器會話,而不是創建多個獨立的請求。我沒有檢查到底發生了什么,但假設瀏覽器終止了現有請求以便在您單擊時運行新請求ctrl-R。服務器看到該請求終止并將其作為上下文取消傳達給您的代碼。
嘗試使用curl或創建獨立請求的其他一些腳本/實用程序來測試您的代碼。我相信在那種情況下您不會看到取消。
- 1 回答
- 0 關注
- 134 瀏覽
添加回答
舉報
0/150
提交
取消
