(runtime api.FunctionRuntime, sources []<-chan contube.Record, sink chan<- contube.Record)
| 69 | } |
| 70 | |
| 71 | func (instance *FunctionInstanceImpl) Run(runtime api.FunctionRuntime, sources []<-chan contube.Record, |
| 72 | sink chan<- contube.Record) { |
| 73 | logger := instance.logger |
| 74 | defer close(sink) |
| 75 | |
| 76 | defer logger.Info("function instance has been stopped") |
| 77 | |
| 78 | logger.Info("function instance is running") |
| 79 | |
| 80 | logCounter := common.LogCounter() |
| 81 | channels := make([]reflect.SelectCase, len(sources)+1) |
| 82 | for i, s := range sources { |
| 83 | channels[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(s)} |
| 84 | } |
| 85 | channels[len(sources)] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(instance.ctx.Done())} |
| 86 | |
| 87 | for len(channels) > 0 { |
| 88 | // Use reflect.Select to select a channel from the slice |
| 89 | chosen, value, ok := reflect.Select(channels) |
| 90 | if !ok { |
| 91 | // The selected channel has been closed, remove it from the slice |
| 92 | channels = append(channels[:chosen], channels[chosen+1:]...) |
| 93 | continue |
| 94 | } |
| 95 | |
| 96 | // Convert the selected value to the type Record |
| 97 | record := value.Interface().(contube.Record) |
| 98 | if logger.DebugEnabled() { |
| 99 | logger.Debug("Calling process function", "count", logCounter) |
| 100 | } |
| 101 | |
| 102 | // Call the processing function |
| 103 | output, err := runtime.Call(record) |
| 104 | if err != nil { |
| 105 | if errors.Is(err, context.Canceled) { |
| 106 | return |
| 107 | } |
| 108 | // Log the error if there's an issue with the processing function |
| 109 | logger.Error(err, "failed to process record") |
| 110 | return |
| 111 | } |
| 112 | |
| 113 | // If the output is nil, continue with the next iteration |
| 114 | if output == nil { |
| 115 | continue |
| 116 | } |
| 117 | |
| 118 | // Try to send the output to the sink, but also listen to the context's Done channel |
| 119 | select { |
| 120 | case sink <- output: |
| 121 | case <-instance.ctx.Done(): |
| 122 | return |
| 123 | } |
| 124 | |
| 125 | // If the selected channel is the context's Done channel, exit the loop |
| 126 | if chosen == len(channels)-1 { |
| 127 | return |
| 128 | } |
nothing calls this directly
no test coverage detected