From 29910d62f98ea579eaaeb3213664c5e5e90d8f57 Mon Sep 17 00:00:00 2001 From: AdzerKI <47555435+AdzerKI@users.noreply.github.com> Date: Mon, 19 Oct 2026 19:08:46 +0300 Subject: [PATCH 1/2] stream: do not re-arm the refresh timer once the worker is exiting --- lib/crowdsec.lua | 4 ++ t/26_stream_timer_worker_exiting.t | 69 +++++++++++++++++++ ...worker_exiting_crowdsec_nginx_bouncer.conf | 18 +++++ 3 files changed, 91 insertions(+) create mode 100644 t/26_stream_timer_worker_exiting.t create mode 100644 t/conf_t/26_stream_timer_worker_exiting_crowdsec_nginx_bouncer.conf diff --git a/lib/crowdsec.lua b/lib/crowdsec.lua index 0bb960f..709e13d 100644 --- a/lib/crowdsec.lua +++ b/lib/crowdsec.lua @@ -493,6 +493,10 @@ function csmod.SetupStream() ngx.log(ngx.ERR, "Failed to query the stream: " .. err) end end + if ngx.worker.exiting() then + ngx.log(ngx.INFO, "worker is exiting, not setting up stream timer") + return + end local ok, err = ngx.timer.at(runtime.conf["UPDATE_FREQUENCY"], SetupStreamTimer) if not ok then error("Failed to create the timer: " .. (err or "unknown")) diff --git a/t/26_stream_timer_worker_exiting.t b/t/26_stream_timer_worker_exiting.t new file mode 100644 index 0000000..a482d53 --- /dev/null +++ b/t/26_stream_timer_worker_exiting.t @@ -0,0 +1,69 @@ +use Test::Nginx::Socket 'no_plan'; + +master_on(); +workers(1); +run_tests(); + +__DATA__ + +=== TEST 26: Stream refresh running when the worker exits + +--- main_config +load_module /usr/share/nginx/modules/ndk_http_module.so; +load_module /usr/share/nginx/modules/ngx_http_lua_module.so; + +--- http_config + +lua_package_path './lib/?.lua;;'; +lua_shared_dict crowdsec_cache 50m; +lua_shared_dict lapi_state 1m; + +init_by_lua_block +{ + cs = require "crowdsec" + local ok, err = cs.init("./t/conf_t/26_stream_timer_worker_exiting_crowdsec_nginx_bouncer.conf", "crowdsec-nginx-bouncer/v1.0.8") + if ok == nil then + ngx.log(ngx.ERR, "[Crowdsec] " .. err) + error() + end +} + +init_worker_by_lua_block { + cs = require "crowdsec" + cs.SetupStream() +} + +server { + listen 8081; + + location = /v1/decisions/stream { + content_by_lua_block { + local args = ngx.req.get_uri_args() + if args.startup ~= "true" then + ngx.shared.lapi_state:set("refreshing", true) + ngx.sleep(1) + end + ngx.say('{"deleted": [], "new": []}') + } + } +} + +--- config + +location = /t { + content_by_lua_block { + for _ = 1, 100 do + if ngx.shared.lapi_state:get("refreshing") then + break + end + ngx.sleep(0.1) + end + ngx.print(tostring(ngx.shared.lapi_state:get("refreshing"))) + } +} + +--- request +GET /t +--- response_body: true +--- no_shutdown_error_log +Failed to create the timer diff --git a/t/conf_t/26_stream_timer_worker_exiting_crowdsec_nginx_bouncer.conf b/t/conf_t/26_stream_timer_worker_exiting_crowdsec_nginx_bouncer.conf new file mode 100644 index 0000000..c7f12fe --- /dev/null +++ b/t/conf_t/26_stream_timer_worker_exiting_crowdsec_nginx_bouncer.conf @@ -0,0 +1,18 @@ +ENABLED=true +API_URL=http://127.0.0.1:8081 +API_KEY=LFrdL+aiecMTSxpGE9vLkx5sGMwdIpgVovpVMfXp3J0 +CACHE_EXPIRATION=1 +BOUNCING_ON_TYPE=all +FALLBACK_REMEDIATION=ban +REQUEST_TIMEOUT=3000 +UPDATE_FREQUENCY=1 +MODE=stream +EXCLUDE_LOCATION=/v1/decisions/stream +BAN_TEMPLATE_PATH=./ban +REDIRECT_LOCATION= +RET_CODE= +CAPTCHA_PROVIDER= +SECRET_KEY= +SITE_KEY= +CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/captcha.html +CAPTCHA_EXPIRATION=3600 From 63e574bec0df85596b60b38b0fd3d5a3ba23b308 Mon Sep 17 00:00:00 2001 From: AdzerKI <47555435+AdzerKI@users.noreply.github.com> Date: Wed, 21 Oct 2026 05:36:03 +0300 Subject: [PATCH 2/2] test: use the placeholder API key in the stream timer test config --- .../26_stream_timer_worker_exiting_crowdsec_nginx_bouncer.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/conf_t/26_stream_timer_worker_exiting_crowdsec_nginx_bouncer.conf b/t/conf_t/26_stream_timer_worker_exiting_crowdsec_nginx_bouncer.conf index c7f12fe..6da57bb 100644 --- a/t/conf_t/26_stream_timer_worker_exiting_crowdsec_nginx_bouncer.conf +++ b/t/conf_t/26_stream_timer_worker_exiting_crowdsec_nginx_bouncer.conf @@ -1,6 +1,6 @@ ENABLED=true API_URL=http://127.0.0.1:8081 -API_KEY=LFrdL+aiecMTSxpGE9vLkx5sGMwdIpgVovpVMfXp3J0 +API_KEY=test_key CACHE_EXPIRATION=1 BOUNCING_ON_TYPE=all FALLBACK_REMEDIATION=ban