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

     1  // Package runtime implements environment for dataflow programs execution.
     2  package runtime
     3  
     4  import (
     5  	"context"
     6  	"errors"
     7  	"fmt"
     8  	"sync"
     9  )
    10  
    11  type Runtime struct {
    12  	connector  Connector
    13  	funcRunner FuncRunner
    14  }
    15  
    16  var ErrNilDeps = errors.New("runtime deps nil")
    17  
    18  func New(connector Connector, funcRunner FuncRunner) Runtime {
    19  	return Runtime{
    20  		connector:  connector,
    21  		funcRunner: funcRunner,
    22  	}
    23  }
    24  
    25  var (
    26  	ErrStartPortNotFound = errors.New("start port not found")
    27  	ErrExitPortNotFound  = errors.New("stop port not found")
    28  	ErrConnector         = errors.New("connector")
    29  	ErrFuncRunner        = errors.New("func runner")
    30  )
    31  
    32  func (r Runtime) Run(ctx context.Context, prog Program) error {
    33  	enter := prog.Ports[PortAddr{Path: "in", Port: "start"}]
    34  	if enter == nil {
    35  		return ErrStartPortNotFound
    36  	}
    37  
    38  	exit := prog.Ports[PortAddr{Path: "out", Port: "stop"}]
    39  	if exit == nil {
    40  		return ErrExitPortNotFound
    41  	}
    42  
    43  	funcRun, err := r.funcRunner.Run(prog.Funcs)
    44  	if err != nil {
    45  		return fmt.Errorf("%w: %v", ErrFuncRunner, err)
    46  	}
    47  
    48  	cancelableCtx, cancel := context.WithCancel(ctx)
    49  
    50  	wg := sync.WaitGroup{}
    51  	wg.Add(2)
    52  
    53  	go func() {
    54  		funcRun(
    55  			context.WithValue(
    56  				cancelableCtx,
    57  				"cancel", //nolint:staticcheck // SA1029
    58  				cancel,
    59  			),
    60  		)
    61  		wg.Done()
    62  	}()
    63  
    64  	go func() {
    65  		r.connector.Connect(cancelableCtx, prog.Connections)
    66  		wg.Done()
    67  	}()
    68  
    69  	go func() {
    70  		enter <- emptyMsg{}
    71  	}()
    72  
    73  	go func() {
    74  		<-exit
    75  		cancel()
    76  	}()
    77  
    78  	wg.Wait()
    79  
    80  	return nil
    81  }