package main import "context" type ( Ingester struct { writer Queue reader Queue process processFunc } processFunc func(context.Context, []byte) ([]byte, error) ) func NewIngester(writer, reader Queue, process processFunc) Ingester { return Ingester{ writer: writer, reader: reader, process: process, } } func (i Ingester) Process(ctx context.Context) error { ctx, can := context.WithCancel(ctx) defer can() for ctx.Err() == nil { reservation, read, err := i.reader.Syn(ctx) if err != nil { return err } processed, err := i.process(ctx, read) if err != nil { return err } if err := i.writer.Enqueue(ctx, processed); err != nil { return err } if err := i.reader.Ack(ctx, reservation); err != nil { return err } } return ctx.Err() }