github.com/chenbh/concourse/v6@v6.4.2/atc/lidar/check_rate_calculator.go (about) 1 package lidar 2 3 import ( 4 "context" 5 "time" 6 7 "golang.org/x/time/rate" 8 ) 9 10 //go:generate counterfeiter . Limiter 11 12 type Limiter interface { 13 Wait(context.Context) error 14 } 15 16 //go:generate counterfeiter . CheckableCounter 17 18 type CheckableCounter interface { 19 CheckableCount() (int, error) 20 } 21 22 type CheckRateCalculator struct { 23 MaxChecksPerSecond int 24 ResourceCheckingInterval time.Duration 25 26 CheckableCounter CheckableCounter 27 } 28 29 // RateLimiter determines the rate at which the checks should be limited to per 30 // second. 31 // 32 // It is dependent on the max checks per second configuration, where if it is 33 // configured to -1 then it there is no limit, if it is > 0 then it is set to 34 // its configured value and if it is 0 (which is default) then it is calculated 35 // using the number of checkables and the resource checking interval. 36 // 37 // The calculated limit is determined by finding the ideal number of checks to 38 // run per second in order to check all the checkables in the database within 39 // the resource checking interval. By enforcing that ideal rate of checks, it 40 // will help spread out the number of checks that are started within the same 41 // interval. 42 func (c CheckRateCalculator) RateLimiter() (Limiter, error) { 43 var rateOfChecks rate.Limit 44 if c.MaxChecksPerSecond == -1 { 45 // UNLIMITED POWER 46 rateOfChecks = rate.Inf 47 } else if c.MaxChecksPerSecond == 0 { 48 // Fetch the number of checkables (resource config scopes) in the database 49 checkableCount, err := c.CheckableCounter.CheckableCount() 50 if err != nil { 51 return nil, err 52 } 53 54 // Calculate the number of checks that need to be run per second in order 55 // to check all the checkables within the resource checking interval 56 everythingRate := float64(checkableCount) / c.ResourceCheckingInterval.Seconds() 57 58 rateOfChecks = rate.Limit(everythingRate) 59 } else { 60 rateOfChecks = rate.Limit(c.MaxChecksPerSecond) 61 } 62 63 return rate.NewLimiter(rateOfChecks, 1), nil 64 }