proxy-pool/internal/adapters/providerapi/execution_limiter.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)
}