github.com/sttk/sabi@v0.5.0/runner.go (about) 1 // Copyright (C) 2022 Takayuki Sato. All Rights Reserved. 2 // This program is free software under MIT License. 3 // See the file LICENSE in this distribution for more details. 4 5 package sabi 6 7 type /* error reasons */ ( 8 // FailToRunInParallel is an error reason which indicates some runner 9 // functions which run in parallel failed. 10 FailToRunInParallel struct { 11 Errors map[int]Err 12 } 13 ) 14 15 // RunSeq is a function which runs specified runner functions sequencially. 16 func RunSeq(runners ...func() Err) Err { 17 for _, runner := range runners { 18 err := runner() 19 if err.IsNotOk() { 20 return err 21 } 22 } 23 return Ok() 24 } 25 26 // Seq is a function which creates a runner function which runs multiple 27 // runner functions specified as arguments sequencially. 28 func Seq(runners ...func() Err) func() Err { 29 return func() Err { 30 return RunSeq(runners...) 31 } 32 } 33 34 type indexedErr struct { 35 index int 36 err Err 37 } 38 39 func RunPara(runners ...func() Err) Err { 40 ch := make(chan indexedErr) 41 42 for i, r := range runners { 43 go func(index int, runner func() Err, ch chan indexedErr) { 44 err := runner() 45 ie := indexedErr{index: index, err: err} 46 ch <- ie 47 }(i, r, ch) 48 } 49 50 errs := make(map[int]Err) 51 n := len(runners) 52 for i := 0; i < n; i++ { 53 select { 54 case ie := <-ch: 55 if ie.err.IsNotOk() { 56 errs[ie.index] = ie.err 57 } 58 } 59 } 60 61 if len(errs) > 0 { 62 return NewErr(FailToRunInParallel{Errors: errs}) 63 } 64 65 return Ok() 66 } 67 68 // Para is a function which creates a runner function which runs multiple 69 // runner functions specified as arguments in parallel. 70 func Para(runners ...func() Err) func() Err { 71 return func() Err { 72 return RunPara(runners...) 73 } 74 }