網頁

2021/10/1

Golang select 逾時處理

Go 利用select設定逾時的方式如下。


Go select可從多個channel的sendreceive隨機選一執行,而time.After(d Duration)設定到時間超過後會回傳一個channel receive,因此可搭配goroutine及channel實現逾時處理。

例如下面呼叫fetch()撈取資料時可能會花一段時間,若撈取執行時間超時則timeout。

建立一個goroutine執行fetch()並將回傳結果發送到channel c。select 選擇<-c取得fetch()回傳結果或tiem.After()回傳的<-chan Tiem代表超時。for迴圈一次一秒,迴圈的次數代表執行的時間。

package main

import (
    "fmt"
    "time"
)

func main() {
    c := make(chan string)

    go func() {
        c <- fetch()
    }()

    select {
    case s := <-c:
        fmt.Println(s)
    case <-time.After(time.Second * 3):
        fmt.Println("timeout")
    }
    close(c)
}

func fetch() string {
    fmt.Print("fetch data")
    for i := 0; i < 5; i++ {
        fmt.Print(".")
        time.Sleep(time.Second)
    }
    fmt.Println()
    return "hello"
}

上面fetch()執行時間為5秒(5次迴圈每次用time.Sleep(time.Second)暫停一秒模擬),而time.After()為3秒,則<-c的阻塞時間超過time.After()設定的時間,因此select會選擇case <-time.After(time.Second * 3)執行結果如下。

fetch data....timeout


沒有留言:

張貼留言