mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
35 lines
905 B
Go
35 lines
905 B
Go
|
package concurrencylimiter
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"runtime"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
// ch is the channel for limiting concurrent inserts.
|
||
|
// Put an item into it before performing an insert and remove
|
||
|
// the item after the insert is complete.
|
||
|
ch = make(chan struct{}, runtime.GOMAXPROCS(-1)*2)
|
||
|
|
||
|
// waitDuration is the amount of time to wait until at least a single
|
||
|
// concurrent insert out of cap(Ch) inserts is complete.
|
||
|
waitDuration = time.Second * 30
|
||
|
)
|
||
|
|
||
|
// Do calls f with the limited concurrency.
|
||
|
func Do(f func() error) error {
|
||
|
// Limit the number of conurrent inserts in order to prevent from excess
|
||
|
// memory usage and CPU trashing.
|
||
|
t := time.NewTimer(waitDuration)
|
||
|
select {
|
||
|
case ch <- struct{}{}:
|
||
|
t.Stop()
|
||
|
err := f()
|
||
|
<-ch
|
||
|
return err
|
||
|
case <-t.C:
|
||
|
return fmt.Errorf("the server is overloaded with %d concurrent inserts; either increase the number of CPUs or reduce the load", cap(ch))
|
||
|
}
|
||
|
}
|