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 }