From 9b8d6b937cff1295a96807c0c0954e8f900adb52 Mon Sep 17 00:00:00 2001 From: mathieuHa Date: Fri, 7 Aug 2026 19:11:54 +0200 Subject: [PATCH] :bug: keep the stream lease alive when updateIntervalSeconds is 1 (#371) * :bug: keep the stream lease alive when updateIntervalSeconds is 1 handleStreamCache takes a lease so a single node polls LAPI per interval, and stores it for updateInterval-1 seconds. The e2e stream scenario now sets updateIntervalSeconds to 1, which makes that a 0 second duration: golang-ttl-map returns early on a zero ttl (map.go:114) and redis rejects a non positive EX, so the lease is never stored and the guard silently does nothing. Floor the duration at 1 second. At an interval of 1 the lease can survive a tick that fires slightly early and cost one skipped poll, which is far better than every node polling every tick against a shared redis. * Adjust lease duration to prevent cache update conflicts Updated lease duration logic to ensure a minimum of 1 second. --------- Co-authored-by: maxlerebourg --- bouncer.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bouncer.go b/bouncer.go index d362996..5f02e27 100644 --- a/bouncer.go +++ b/bouncer.go @@ -641,7 +641,12 @@ func handleStreamCache(bouncer *Bouncer) error { if err.Error() != cache.CacheMiss { return err } - bouncer.cacheClient.Set(cacheTimeoutKey, cache.NoBannedValue, bouncer.updateInterval-1) + // To avoid every instance trying to update the cache, set 1 second at least + leaseDuration := bouncer.updateInterval - 1 + if leaseDuration < 1 { + leaseDuration = 1 + } + bouncer.cacheClient.Set(cacheTimeoutKey, cache.NoBannedValue, leaseDuration) streamRouteURL := url.URL{ Scheme: bouncer.crowdsecScheme, Host: bouncer.crowdsecHost,