cleanup
This commit is contained in:
parent
2866936856
commit
c96a21e423
170
adapative.go
170
adapative.go
@ -64,174 +64,46 @@ func (a *adaptive) nightshiftTO() time.Duration {
|
||||
return to
|
||||
}
|
||||
|
||||
// ensure that a single client does not get freed if using it
|
||||
// ensure that eventually gets collected if not using it
|
||||
// ensure that the background job is not running forever
|
||||
// handle load as well
|
||||
|
||||
func (a *adaptive) nightshift(s Stats, now time.Time) time.Duration {
|
||||
// idle, inactive, uninitialized => not idle, initialize, 0
|
||||
// idle, inactive, initialized => to
|
||||
// idle, active, uninitialized => not idle, initialize, 0
|
||||
// idle, active, initialized => not idle, initialize, 0
|
||||
// not idle, inactive, uninitialized => not idle, initialize, 0
|
||||
// not idle, inactive, initialized => idle, new to
|
||||
// not idle, active, uninitialized => not idle, initialize, 0
|
||||
// not idle, active, initialized => 0
|
||||
|
||||
// idle := a.idle
|
||||
// active := s.Active > 0
|
||||
// initialized := !a.activeTime.IsZero()
|
||||
// if !initialized {
|
||||
// a.idle = false
|
||||
// a.activeTime = now
|
||||
// return 0
|
||||
// }
|
||||
|
||||
// if idle && !active {
|
||||
// return a.nsTO
|
||||
// }
|
||||
|
||||
// if idle {
|
||||
// a.idle = false
|
||||
// a.nsTO = 0
|
||||
// a.activeTime = now
|
||||
// return 0
|
||||
// }
|
||||
|
||||
// if active {
|
||||
// return 0
|
||||
// }
|
||||
|
||||
// a.idle = true
|
||||
// a.nsTO = nightshiftTO(a.activeTime, now)
|
||||
// return a.nsTO
|
||||
|
||||
// --
|
||||
|
||||
// state flags:
|
||||
// - initialized
|
||||
// - pempty
|
||||
// - pactive
|
||||
// - empty
|
||||
// - active
|
||||
// actions:
|
||||
// - start active
|
||||
// - call to
|
||||
// - update prev state on every call
|
||||
// states:
|
||||
// X not initialized, not pempty, not pactive, not empty, not active
|
||||
// X not initialized, not pempty, not pactive, not empty, active
|
||||
// X not initialized, not pempty, not pactive, empty, not active
|
||||
// X not initialized, not pempty, not pactive, empty, active
|
||||
// X not initialized, not pempty, pactive, not empty, not active
|
||||
// X not initialized, not pempty, pactive, not empty, active
|
||||
// X not initialized, not pempty, pactive, empty, not active
|
||||
// X not initialized, not pempty, pactive, empty, active
|
||||
// * not initialized, pempty, not pactive, not empty, not active => start active, call to
|
||||
// * not initialized, pempty, not pactive, not empty, active => start active
|
||||
// X not initialized, pempty, not pactive, empty, not active
|
||||
// X not initialized, pempty, not pactive, empty, active
|
||||
// X not initialized, pempty, pactive, not empty, not active
|
||||
// X not initialized, pempty, pactive, not empty, active
|
||||
// X not initialized, pempty, pactive, empty, not active
|
||||
// X not initialized, pempty, pactive, empty, active
|
||||
// * initialized, not pempty, not pactive, not empty, not active => end active, call to
|
||||
// * initialized, not pempty, not pactive, not empty, active => start active
|
||||
// * initialized, not pempty, not pactive, empty, not active => noop
|
||||
// * initialized, not pempty, not pactive, empty, active => start active
|
||||
// * initialized, not pempty, pactive, not empty, not active => end active, call to
|
||||
// * initialized, not pempty, pactive, not empty, active => noop
|
||||
// * initialized, not pempty, pactive, empty, not active => end active, noop
|
||||
// * initialized, not pempty, pactive, empty, active => noop
|
||||
// * initialized, pempty, not pactive, not empty, not active => call to
|
||||
// * initialized, pempty, not pactive, not empty, active => start active
|
||||
// * initialized, pempty, not pactive, empty, not active => noop
|
||||
// * initialized, pempty, not pactive, empty, active => start active
|
||||
// * initialized, pempty, pactive, not empty, not active => end active, call to
|
||||
// * initialized, pempty, pactive, not empty, active => noop
|
||||
// - initialized, pempty, pactive, empty, not active => end active, noop
|
||||
// * initialized, pempty, pactive, empty, active => noop
|
||||
|
||||
pempty := a.prevState.Idle == 0
|
||||
func (a *adaptive) nightshift(s Stats) time.Duration {
|
||||
pactive := a.prevState.Active > 0
|
||||
empty := s.Idle == 0
|
||||
active := s.Active > 0
|
||||
a.prevState = s
|
||||
|
||||
// not initialized, pempty, not pactive, not empty, not active => start active, call to
|
||||
if !a.initialized && pempty && !pactive && !empty && !active {
|
||||
a.initialized = true
|
||||
a.activeStart = now
|
||||
return a.nightshiftTO()
|
||||
}
|
||||
|
||||
// not initialized, pempty, not pactive, not empty, active => start active
|
||||
if !a.initialized && pempty && !pactive && !empty && active {
|
||||
a.initialized = true
|
||||
a.activeStart = now
|
||||
return 0
|
||||
}
|
||||
|
||||
// on the first put we need to set an active start time:
|
||||
if !a.initialized {
|
||||
a.initialized = true
|
||||
a.activeStart = a.clock.Now()
|
||||
if active {
|
||||
return 0
|
||||
}
|
||||
|
||||
// initialized, not pempty, not pactive, not empty, not active => end active, call to
|
||||
if !pempty && !pactive && !empty && !active {
|
||||
ns := a.nightshiftTO()
|
||||
return ns
|
||||
}
|
||||
|
||||
// initialized, not pempty, not pactive, not empty, active => start active
|
||||
// initialized, not pempty, not pactive, empty, active => start active
|
||||
if !pempty && !pactive && active {
|
||||
a.activeStart = now
|
||||
return 0
|
||||
}
|
||||
|
||||
// initialized, not pempty, pactive, not empty, not active => end active, call to
|
||||
if !pempty && pactive && !empty && !active {
|
||||
a.activeEnd = now
|
||||
ns := a.nightshiftTO()
|
||||
return ns
|
||||
}
|
||||
|
||||
// initialized, not pempty, pactive, empty, not active => end active, noop
|
||||
if !pempty && pactive && empty && !active {
|
||||
a.activeEnd = now
|
||||
return 0
|
||||
}
|
||||
|
||||
// initialized, pempty, not pactive, not empty, not active => call to
|
||||
if pempty && !pactive && !empty && !active {
|
||||
return a.nightshiftTO()
|
||||
}
|
||||
|
||||
// initialized, pempty, not pactive, not empty, active => start active
|
||||
// initialized, pempty, not pactive, empty, active => start active
|
||||
if pempty && !pactive && active {
|
||||
a.activeStart = now
|
||||
return 0
|
||||
}
|
||||
|
||||
// initialized, pempty, pactive, not empty, not active => end active, call to
|
||||
if pempty && pactive && !empty && !active {
|
||||
a.activeEnd = now
|
||||
if !pactive && !active && !empty {
|
||||
return a.nightshiftTO()
|
||||
}
|
||||
|
||||
// initialized, pempty, pactive, empty, not active => end active, noop
|
||||
if pempty && pactive && empty && !active {
|
||||
a.activeEnd = now
|
||||
if !pactive && active {
|
||||
a.activeStart = a.clock.Now()
|
||||
return 0
|
||||
}
|
||||
|
||||
if pactive && !active {
|
||||
a.activeEnd = a.clock.Now()
|
||||
if empty {
|
||||
return 0
|
||||
}
|
||||
|
||||
return a.nightshiftTO()
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (a *adaptive) Target(s Stats) (int, time.Duration) {
|
||||
t := a.target(s) // handle when t < 2
|
||||
t := a.target(s)
|
||||
|
||||
// magic number 2: we allow max 2 idle items to be collected only by the nightshift, to provide better
|
||||
// support for sporadic requests, when it's active or just going inactive:
|
||||
@ -239,9 +111,7 @@ func (a *adaptive) Target(s Stats) (int, time.Duration) {
|
||||
t = 2
|
||||
}
|
||||
|
||||
// TODO: optimize, only take the clock when necessary
|
||||
ns := a.nightshift(s, a.clock.Now())
|
||||
|
||||
ns := a.nightshift(s)
|
||||
return t, ns
|
||||
}
|
||||
|
||||
@ -251,5 +121,5 @@ func (a *adaptive) Load(n int) {
|
||||
a.average += float64(n)
|
||||
s := a.prevState
|
||||
s.Idle += n
|
||||
a.nightshift(s, a.clock.Now())
|
||||
a.nightshift(s)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user