52 lines
899 B
Go
52 lines
899 B
Go
package providerapi
|
|
|
|
import "context"
|
|
|
|
const maxTemplateExecutions = 64
|
|
|
|
type executionLimiter struct {
|
|
slots chan struct{}
|
|
}
|
|
|
|
func newExecutionLimiter(limit int) *executionLimiter {
|
|
if limit <= 0 {
|
|
limit = 1
|
|
}
|
|
if limit > maxTemplateExecutions {
|
|
limit = maxTemplateExecutions
|
|
}
|
|
return &executionLimiter{slots: make(chan struct{}, limit)}
|
|
}
|
|
|
|
func (l *executionLimiter) Run(ctx context.Context, execute func() error) error {
|
|
if err := ctx.Err(); err != nil {
|
|
return err
|
|
}
|
|
select {
|
|
case l.slots <- struct{}{}:
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
}
|
|
if err := ctx.Err(); err != nil {
|
|
<-l.slots
|
|
return err
|
|
}
|
|
|
|
completed := make(chan error, 1)
|
|
go func() {
|
|
defer func() { <-l.slots }()
|
|
completed <- execute()
|
|
}()
|
|
|
|
select {
|
|
case err := <-completed:
|
|
return err
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
}
|
|
}
|
|
|
|
func (l *executionLimiter) InFlight() int {
|
|
return len(l.slots)
|
|
}
|