99 lines
1.5 KiB
Go
99 lines
1.5 KiB
Go
package pool
|
|
|
|
import (
|
|
"code.squareroundforest.org/arpio/times"
|
|
"time"
|
|
)
|
|
|
|
type maxTimeout struct {
|
|
clock times.Clock
|
|
max int
|
|
to time.Duration
|
|
items []time.Time
|
|
lastPut int
|
|
}
|
|
|
|
func makeMaxTimeout(max int, to time.Duration) *maxTimeout {
|
|
return &maxTimeout{
|
|
max: max,
|
|
to: to,
|
|
}
|
|
}
|
|
|
|
func (a *maxTimeout) setClock(c times.Clock) {
|
|
a.clock = c
|
|
}
|
|
|
|
func (a *maxTimeout) Target(s Stats) (int, time.Duration) {
|
|
if a.max <= 0 && a.to <= 0 {
|
|
return s.Idle, 0
|
|
}
|
|
|
|
if a.max > 0 && a.to <= 0 {
|
|
t := s.Idle
|
|
if t > a.max {
|
|
t = a.max
|
|
}
|
|
|
|
return t, 0
|
|
}
|
|
|
|
var zero time.Time
|
|
if len(a.items) > s.Idle {
|
|
for i := s.Idle; i < len(a.items); i++ {
|
|
a.items[i] = zero
|
|
}
|
|
|
|
a.items = a.items[:s.Idle]
|
|
if len(a.items) == 0 {
|
|
a.items = nil
|
|
}
|
|
}
|
|
|
|
now := a.clock.Now()
|
|
for len(a.items) < s.Idle {
|
|
a.items = append(a.items, now)
|
|
}
|
|
|
|
puts := s.Put - a.lastPut
|
|
if puts > 0 && len(a.items) >= puts {
|
|
a.lastPut = s.Put
|
|
for i := len(a.items) - puts; i < len(a.items); i++ {
|
|
a.items[i] = now
|
|
}
|
|
}
|
|
|
|
var drop int
|
|
for drop < len(a.items) && a.items[drop].Add(a.to).Before(now) {
|
|
a.items[drop] = zero
|
|
drop++
|
|
}
|
|
|
|
if drop > 0 {
|
|
a.items = a.items[drop:]
|
|
}
|
|
|
|
if len(a.items) == 0 {
|
|
a.items = nil
|
|
return 0, 0
|
|
}
|
|
|
|
t := len(a.items)
|
|
if a.max > 0 && t > a.max {
|
|
t = a.max
|
|
}
|
|
|
|
return t, a.items[0].Add(a.to).Sub(now)
|
|
}
|
|
|
|
func (a *maxTimeout) Load(n int) {
|
|
if a.to <= 0 {
|
|
return
|
|
}
|
|
|
|
now := a.clock.Now()
|
|
for i := 0; i < n; i++ {
|
|
a.items = append(a.items, now)
|
|
}
|
|
}
|