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) }