iT邦幫忙

3

Go synctest:徹底解決並發測試的痛點

  • 分享至 

  • xImage
  •  

完整內容在此, 幹話王_Go synctest:徹底解決並發測試的痛點

Go 語言以 goroutine 和 channel 聞名,併發測試場景卻常常讓人頭痛:
sleep 不夠會 fail,sleep 太久拖慢 CI,偶發錯誤難以重現。

Go 1.24 開始,提供了一個令人振奮的實驗性測試新功能:synctest
讓這一切成為過去!!預計將在 8 月釋出的 Go 1.25 正式釋出。

為什麼傳統並發測試這麼難寫?

讓我們看一個常見的例子:
假設你要測試一個 goroutine 工作是否如期完成。

func TestWorker(t *testing.T) {
    done := make(chan struct{})
    go func() {
        // do some work
        time.Sleep(100 * time.Millisecond)
        close(done)
    }()
    time.Sleep(150 * time.Millisecond) // 等 goroutine 做完
    select {
    case <-done:
        // ok
    default:
        t.Fatal("worker 未完成")
    }
}

問題在哪?

  • 你只能靠 sleep「猜」goroutine 完成的時機

  • sleep 太短測試會 fail,太長又浪費時間

  • 在 CI 跑多次還是可能偶爾 fail

  • 很難精確同步 goroutine 狀態

testing/synctest:用「泡泡」模型徹底解決同步問題

synctest 的核心在於「泡泡」(bubble)與「穩定阻塞」(durably blocked)同步模型。

什麼是「泡泡」?

  • synctest.Run 包起來的程式碼和其 goroutine,會被放進一個「泡泡」

  • 泡泡內的 goroutine 只能互相影響,和外部世界隔離

  • 泡泡追蹤所有在裡面建立的 channel、timer、WaitGroup 等同步物件

什麼是「穩定阻塞」?

  • 當泡泡裡所有 goroutine 都卡住,而且只能被泡泡內其他 goroutine 喚醒,這時就叫做「穩定阻塞」

  • 這時呼叫 synctest.Wait() 會立刻返回

  • 若泡泡內沒有人能再被解鎖,代表死鎖,Run 會 panic

  • 若有 timer 等待,fake clock 會自動快轉到下一個事件

完整內容在此, 幹話王_Go synctest:徹底解決並發測試的痛點


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言