I need to write ExecutePipeline(ctx context.Context, in In, stages ...Stage) Out
, that need to pass all objects of the in
channel through stages
. The problem is that I don't understand how the pipeline can be stopped by the ctx
context if Stage doesn't receive a context.
// each stage function corresponds to the following pattern
func Stage1(in In) (out Out) {
out := make(chan any)
go func() {
// do something..
}()
return out
}
//function signatures cannot be changed!
type (
In <-chan any
Out = In
)
type Stage func(in In) (out Out)
func ExecutePipeline(ctx context.Context, in In, stages ...Stage) Out {
//need to implement this
}
The more specific case I have encountered:
func SimpleTest() {
//init stages here...
in := make(chan any)
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*100))
defer cancel()
stopGenCh := make(chan struct{})
defer close(stopGenCh)
// gen values forever
go func() {
defer close(in)
i := 0
for {
select {
case <-stopGenCh:
return
default:
in <- i
i++
}
}
}()
result := make([]string, 0, 10)
for s := range ExecutePipeline(ctx, in, stages...) { //endless loop
result = append(result, s.(string))
}
}