LoginSignup
0
0

goroutineで並行処理しない処理を作った話

Posted at

初めに

goroutineといえばgolangで並行処理を実装するための言語機能ですが、それを使いあえて並行処理を行わず、Timeoutイベントを取るためだけに使ったコードをシェアします

背景

とあるDBサービスのデータをバックアップするために、そのDBサービスが提供するコマンドラインツールを使う必要がありました
ですが、いつまで経ってもレスポンスが返ってこないことがありました

その対応として、一定期間レスポンスが返ってこない場合に、中断しリトライするようにしました

なお、初めは全テーブル並行処理で実行したのですが、DBサービス側での制限があるようで安定したレスポンスが得られなかったので、1テーブルづつの実行に変更しました

download.go
// download and return to channel
func worker(table string, dt string, ch chan Result) {

	err := exec.Command("コマンドラインツール",
		"-a", "aaa",
		"-b", "bbb").Run()
	if err != nil {
		zap.S().Errorf("%s: %v", table, err)
		ch<- Result{table: table, err: err}
		return
	}
	ch<- Result{table: table, err: nil}
}

func execDownload(tables []string, dt string) []string {
	// channel use only timeout event
	ch := make(chan Result, 1)
	var finTables []string

	// call go routine and download
	for _, table := range tables {
		go func(table string) {
			zap.S().Infof("Start: %s", table)
			worker(table, dt, ch)
		}(table)

		select {
		case result := <-ch:
			if result.err == nil {
				zap.S().Infof("Finish: %s", result.table)
				finTables = append(finTables, result.table)
			} else {
				zap.S().Errorf("Error: %s, %v", result.table, result.err)
			}
		case <-time.After(time.Minute * 3):
			zap.S().Info("TIMEOUT")
		}
	}

	return finTables
}

(業務に関連しそうな所は書き換えています)

main関数から、ダウンロード対象となるテーブルのスライスを渡してループし、go funcからworker関数でダウンロードコマンドを実行します
本来であれば全テーブル並行で動くところですが、channelの数を1つにしているため、ダウンロードが終了し、channelに戻り値を書き込まれるまでブロックされるので、1テーブルづつの実行となります

ダウンロードが成功したテーブルをmain関数に返し、未処理のテーブルのみをリトライするようにしています

補足

こういった処理はスクリプト系で書けば簡単に実装出来そうですが、ダウンロード以外にも必要な処理があり、それはnodeを必要としていました
nodeで実装しようとしましたが、nodeとTimeoutイベントがちょっと相性悪そうだったのと、コンテナでの実行が前提となっているため、nodeの上に新たに他のスクリプト環境を上乗せするのは、筋が悪いように思われました
このような理由で、1バイナリで完結するgolangで実装することにしました

終わりに

この記事が何方かのお役に立つと嬉しく思います

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0