mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-12 16:47:41 +02:00
authorize: build evaluators cache in parallel (#4731)
authorize: build evaluators cache in parallel (#4722) * authorize: build evaluators cache in parallel * session: add unit tests for gRPC wrapper methods (#4713) * core/config: add support for maps in environments (#4717) * reconciler: allow custom comparison function (#4726) * add loopvar alias --------- Co-authored-by: Denis Mishin <dmishin@pomerium.com> Co-authored-by: Kenneth Jenkins <51246568+kenjenkins@users.noreply.github.com> Co-authored-by: Caleb Doxsey <cdoxsey@pomerium.com>
This commit is contained in:
parent
34187e8ba5
commit
6cec77bad5
3 changed files with 116 additions and 31 deletions
54
internal/errgrouputil/builder.go
Normal file
54
internal/errgrouputil/builder.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Package errgrouputil contains methods for working with errgroup code.
|
||||
package errgrouputil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/slices"
|
||||
)
|
||||
|
||||
// BuilderFunc is a function that builds a value of type T
|
||||
type BuilderFunc[T any] func(ctx context.Context) (*T, error)
|
||||
|
||||
// Build builds a slice of values of type T using the provided builders concurrently
|
||||
// and returns the results and any errors.
|
||||
func Build[T any](
|
||||
ctx context.Context,
|
||||
builders ...BuilderFunc[T],
|
||||
) ([]*T, []error) {
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
eg.SetLimit(runtime.NumCPU()/2 + 1)
|
||||
|
||||
results := make([]*T, len(builders))
|
||||
errors := make([]error, len(builders))
|
||||
|
||||
fn := func(i int) func() error {
|
||||
return func() error {
|
||||
result, err := builders[i](ctx)
|
||||
if err != nil {
|
||||
errors[i] = err
|
||||
return nil
|
||||
}
|
||||
results[i] = result
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
for i := range builders {
|
||||
eg.Go(fn(i))
|
||||
}
|
||||
|
||||
err := eg.Wait()
|
||||
if err != nil {
|
||||
return nil, []error{err} // not happening
|
||||
}
|
||||
|
||||
return slices.Filter(results, func(t *T) bool {
|
||||
return t != nil
|
||||
}), slices.Filter(errors, func(err error) bool {
|
||||
return err != nil
|
||||
})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue