github.com/yandex/pandora@v0.5.32/core/schedule/line.go (about) 1 package schedule 2 3 import ( 4 "math" 5 "time" 6 7 "github.com/yandex/pandora/core" 8 ) 9 10 func NewLine(from, to float64, duration time.Duration) core.Schedule { 11 if from == to { 12 return NewConst(from, duration) 13 } 14 a := (to - from) / float64(duration/1e9) 15 b := from 16 xn := float64(duration) / 1e9 17 n := int64(a*xn*xn/2 + b*xn) 18 return NewDoAtSchedule(duration, n, lineDoAt(a, b)) 19 } 20 21 type LineConfig struct { 22 From float64 `validate:"min=0"` 23 To float64 `validate:"min=0"` 24 Duration time.Duration `validate:"min-time=1ms"` 25 } 26 27 func NewLineConf(conf LineConfig) core.Schedule { 28 return NewLine(conf.From, conf.To, conf.Duration) 29 } 30 31 // x - duration from 0 to max. 32 // RPS(x) = a * x + b // Line RPS schedule. 33 // Number of shots from 0 to x = integral(RPS) from 0 to x = (a*x^2)/2 + b*x 34 // Has shoot i. When it should be? i = (a*x^2)/2 + b*x => x = (sqrt(2*a*i + b^2) - b) / a 35 func lineDoAt(a, b float64) func(i int64) time.Duration { 36 // Some common calculations. 37 twoA := 2 * a 38 bSquare := b * b 39 bilionDivA := 1e9 / a 40 return func(i int64) time.Duration { 41 //return time.Duration((math.Sqrt(2*a*float64(i)+b*b) - b) * 1e9 / a) 42 return time.Duration((math.Sqrt(twoA*float64(i)+bSquare) - b) * bilionDivA) 43 } 44 }