From 0ed815434061f8641d42229654dfb3b32819c45d Mon Sep 17 00:00:00 2001 From: mhx Date: Fri, 31 Jul 2026 19:21:06 +0200 Subject: [PATCH] :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. --- bouncer.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bouncer.go b/bouncer.go index d362996..6275248 100644 --- a/bouncer.go +++ b/bouncer.go @@ -641,7 +641,13 @@ func handleStreamCache(bouncer *Bouncer) error { if err.Error() != cache.CacheMiss { return err } - bouncer.cacheClient.Set(cacheTimeoutKey, cache.NoBannedValue, bouncer.updateInterval-1) + // The lease expires just before the next tick, but it also has to be stored at all: + // the local cache ignores a zero duration and redis rejects a non positive EX. + 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,