Like Prometheus, but for logs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
loki/pkg/querier/queryrange/queryrangebase/util.go

60 lines
1.3 KiB

package queryrangebase
import (
"context"
)
// RequestResponse contains a request response and the respective request that was used.
type RequestResponse struct {
Request Request
Response Response
}
// DoRequests executes a list of requests in parallel.
func DoRequests(ctx context.Context, downstream Handler, reqs []Request, parallelism int) ([]RequestResponse, error) {
// If one of the requests fail, we want to be able to cancel the rest of them.
ctx, cancel := context.WithCancel(ctx)
defer cancel()
// Feed all requests to a bounded intermediate channel to limit parallelism.
intermediate := make(chan Request)
go func() {
for _, req := range reqs {
intermediate <- req
}
close(intermediate)
}()
respChan, errChan := make(chan RequestResponse), make(chan error)
if parallelism > len(reqs) {
parallelism = len(reqs)
}
for i := 0; i < parallelism; i++ {
go func() {
for req := range intermediate {
resp, err := downstream.Do(ctx, req)
if err != nil {
errChan <- err
} else {
respChan <- RequestResponse{req, resp}
}
}
}()
}
resps := make([]RequestResponse, 0, len(reqs))
var firstErr error
for range reqs {
select {
case resp := <-respChan:
resps = append(resps, resp)
case err := <-errChan:
if firstErr == nil {
cancel()
firstErr = err
}
}
}
return resps, firstErr
}