使用Gin Request Context可能遇到的問題(附解法)

撰文原因 問題程式碼(範例) 解法 1. 暫時先傳 context.TODO() 2. 使用 context.WithoutCancel 3. 不要用go關鍵字 結語 參考資料 撰文原因 最近工作遇到服務使用的新方法需要傳遞context到函數中執行, 結果導致本來要跑在背景任務沒完成(ex: 通知訊息/發送郵件)。 問題程式碼(範例) 事情是因為傳入的是 c.Request.Context(),然而這個gin所實作的Context在回應HTTP Response結束時會自動取消, 導致引用ctx的do函數在Context連帶著被取消後內部的函數也跟著取消。 程式碼範例如下: package main import ( "context" "fmt" "net/http" "time" "github.com/gin-gonic/gin" ) func main() { // Create a Gin router with default middleware (logger and recovery) r := gin.Default() // Define a simple GET endpoint r.GET("/ping", func(c *gin.Context) { go doWork(c.Request.Context()) time.Sleep(2 * time.Second) // Return JSON response c.JSON(http.StatusOK, gin.H{ "message": "pong", }) }) r.Run("127.0.0.1:8080") } func doWork(ctx context.Context) { defer ctx.Done() elapsed := 0 * time.Millisecond for { select { case <-ctx.Done(): // Check if the context is done (cancelled or timed out) fmt.Printf("worker stopped err: %v\n", ctx.Err()) return default: secs := 500 * time.Millisecond fmt.Printf("working... %v passed\n", elapsed) time.Sleep(secs) elapsed += secs } if elapsed >= 5*time.Second { fmt.Println("worker completed") break } } } 實際跑起來會發現doWork只是每0.5秒印出一段訊息,原本預期最多跑5秒就會結束, 然而實際上2秒就會因為gin response被標記為完成自動結束, 這邊只是粗略模擬尊重context機制的函式庫的行為(qmgo…), 當select捕捉到<-ctx.Done()會停止或取消後續的行為。 ...

October 5, 2025 · 1 min · 宗嘉

[Debug過程] 學Hugo並發布到Github page

前言 如果你正在尋找一篇Hugo建立GithubPag的教學文,請你繼續搜尋其他文章, 因為這是我第一次使用Hugo跌跌撞撞的除錯紀錄, 而大部分問題都是我自己不照教學走導致需要Debug的文章, 但如果想知道怎麼出錯解錯就繼續看下去,但不建議跟著做下去。 Bug1 前幾次hugo server -D啟動正常,後來卻出錯? 本來想說安裝extended版本比較好,所以重新用snap安裝穩定版, 結果啟動伺服器得到以下結果: hugo v0.89.4 linux/amd64 BuildDate=2021-11-17T14:49:26Z Error: Error building site: TOCSS: failed to transform "ananke/css/main.css" (text/css). Check your Hugo installation; you need the extended version to build SCSS/SASS.: this feature is not available in your current Hugo version, see https://goo.gl/YMrWcn for more information Built in 14 ms 我是在Ubuntu的環境下用 snap install hugo安裝Hugo, 而錯誤的原因是用extended版產生部落格,後面又重新切換Hugo穩定版, 但原本的部落格資料需要SCSS/SASS的支援所以才會出現這樣的錯誤。 解法 因為懶得重新生成檔案,乾脆就用SCSS版本的Hugo: snap remove hugo snap install hugo --channel=extended 或是使用官方提供的方法切換版本: snap refresh hugo --channel=extended 產生一個GithubPage的儲存庫 基本上遇到的問題也只有上面的版本問題, 接著一路照著官方教學建立文章看結果, 最後使用hugo -D 建立靜態的HTML檔案,確認public資料夾是否產生資料。 ...

November 27, 2021 · 2 min · 宗嘉