From c96a21e42368d0d216f289b64a9f5741a1f324c8 Mon Sep 17 00:00:00 2001 From: Arpad Ryszka Date: Sun, 15 Mar 2026 17:44:03 +0100 Subject: [PATCH] cleanup --- adapative.go | 174 +++++++-------------------------------------------- 1 file changed, 22 insertions(+), 152 deletions(-) diff --git a/adapative.go b/adapative.go index 94748ca..c0cc002 100644 --- a/adapative.go +++ b/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 { - return 0 - } + 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) }