github.com/EagleQL/Xray-core@v1.4.3/common/task/task.go (about)

     1  package task
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/xtls/xray-core/common/signal/semaphore"
     7  )
     8  
     9  // OnSuccess executes g() after f() returns nil.
    10  func OnSuccess(f func() error, g func() error) func() error {
    11  	return func() error {
    12  		if err := f(); err != nil {
    13  			return err
    14  		}
    15  		return g()
    16  	}
    17  }
    18  
    19  // Run executes a list of tasks in parallel, returns the first error encountered or nil if all tasks pass.
    20  func Run(ctx context.Context, tasks ...func() error) error {
    21  	n := len(tasks)
    22  	s := semaphore.New(n)
    23  	done := make(chan error, 1)
    24  
    25  	for _, task := range tasks {
    26  		<-s.Wait()
    27  		go func(f func() error) {
    28  			err := f()
    29  			if err == nil {
    30  				s.Signal()
    31  				return
    32  			}
    33  
    34  			select {
    35  			case done <- err:
    36  			default:
    37  			}
    38  		}(task)
    39  	}
    40  
    41  	for i := 0; i < n; i++ {
    42  		select {
    43  		case err := <-done:
    44  			return err
    45  		case <-ctx.Done():
    46  			return ctx.Err()
    47  		case <-s.Wait():
    48  		}
    49  	}
    50  
    51  	return nil
    52  }