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  }