🐈

【Go】Goルーチンを利用時に特定処理のタイムアウトをチェックする

2022/11/17に公開

Goの並行処理の実行時に、doneチャンネルとselect文を利用した、timeoutチェックの実行サンプルになります。
select文を利用することにより、複数のチャンネルに対する読み込み囲み込み操作が可能になりますが、下記のようにcaseに設定するチャンネルに、time.Afterを設定することにより、対象処理の実行時間が超過した場合、エラーを返すことが可能になります。

package main
import (
	"errors"
	"fmt"
	"time"
)

func timeLimit() (int, error) {
	var result int
	var err error

	// 値を受け渡さないdoneチャンネルを作成
	done := make(chan struct{})

	go func() {
	     // 特定の処理の呼び出し
		reslut, err := doSomeWork()
		if err != nil {
			fmt.Println(reslut)
		}
		close(done)
	}()


      // doSomeWorkを呼び出し時にタイムアウトした場合、
	select {
	// doneチャンネルからの値の取得を変数で受けずに無視
	// 本来は v:= <-doneのようにチャンネルから値を受けたりする
	case <-done:
		return result, err
	// timeLimit関数とGoルーチンは別で実行されているので、
	// doSomeWorkで実行時間を超過するとcaseでtime.Afterの方が実行される
	case <-time.After(2 * time.Second):
		return 0, errors.New("timeout")
	}
}

func doSomeWork() (result int, err error) {
	// time.Sleep(time.Second * 10)
	return 0, nil
}

func main() {
	fmt.Println(timeLimit())
}

参考書籍
初めてのGo言語[https://www.amazon.co.jp/dp/4814400047/]

Discussion