github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/runtime/func_runner.go (about)

     1  package runtime
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"sync"
     7  )
     8  
     9  type FuncRunner struct {
    10  	registry map[string]FuncCreator
    11  }
    12  
    13  type FuncCreator interface {
    14  	// Create method validates the input and builds ready to use function
    15  	Create(funcIO FuncIO, msg Msg) (func(context.Context), error)
    16  }
    17  
    18  func (d FuncRunner) Run(funcCalls []FuncCall) (func(ctx context.Context), error) {
    19  	funcs := make([]func(context.Context), len(funcCalls))
    20  
    21  	for i, call := range funcCalls {
    22  		creator, ok := d.registry[call.Ref]
    23  		if !ok {
    24  			return nil, fmt.Errorf("func creator not found: %v", call.Ref)
    25  		}
    26  
    27  		handler, err := creator.Create(call.IO, call.ConfigMsg)
    28  		if err != nil {
    29  			return nil, fmt.Errorf("create: %w: %v", err, call.Ref)
    30  		}
    31  
    32  		funcs[i] = handler
    33  	}
    34  
    35  	return func(ctx context.Context) {
    36  		wg := sync.WaitGroup{}
    37  		wg.Add(len(funcs))
    38  		for i := range funcs {
    39  			routine := funcs[i]
    40  			go func() {
    41  				routine(ctx)
    42  				wg.Done()
    43  			}()
    44  		}
    45  		wg.Wait()
    46  	}, nil
    47  }
    48  
    49  func MustNewFuncRunner(registry map[string]FuncCreator) FuncRunner {
    50  	if registry == nil {
    51  		panic(ErrNilDeps)
    52  	}
    53  	return FuncRunner{registry: registry}
    54  }