goroutine を複数起動してどれか一つがエラーになった時の終了する

{
    broadCastChan := make(chan struct{}, 1)
    stopChan := make(chan struct{}, len(workers))
    var wg sync.WaitGroup

    for _, worker := range workers {
        wg.Add(1)
        go func(worker *Worker) {
            defer wg.Done()
            err := worker.Work(broadCastChan)
            log.Println(err)
            stopChan <- struct{}{}
        }(worker)
    }

    <-stopChan
    close(broadCastChan)
    wg.Wait()
}

stopChan に <- struct{}{} する際に block しないように worker 数を capacity に指定。 stopChan で一つでも受け取ったら broadCastChan を close して worker の中で

{
    for {
        select {
        case <-broadCastChan:
            // exit
            return
        default:
            // do something
        }
    }
}

みたいな感じで待っておいて各 worker を終了。

wg.Wait で全ての worker が終わるまで待つ。

こんな感じかなぁ。

青い花 1-8

青い花(1)

青い花(1)

青い花(2)

青い花(2)

青い花(3)

青い花(3)

青い花(4)

青い花(4)

青い花(5)

青い花(5)

青い花(6)

青い花(6)

青い花(7)

青い花(7)

青い花(8)

青い花(8)

クリムゾンの迷宮

(恐らく)中学生の頃に読んだ青の炎より前の作品を今頃読むのもなんだか面白いなぁと思った。