1

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))
        }
}
Demps
  • 21
  • 2

0 Answers0