diff --git a/.github/workflows/build_and_test_with_resty_events.yml b/.github/workflows/build_and_test_with_resty_events.yml index cb7abf07..fc65c461 100644 --- a/.github/workflows/build_and_test_with_resty_events.yml +++ b/.github/workflows/build_and_test_with_resty_events.yml @@ -147,4 +147,4 @@ jobs: run: | eval `luarocks path` eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) - TEST_NGINX_RANDOMIZE=1 prove -I. -r t/with_resty-events + TEST_NGINX_TIMEOUT=4 TEST_NGINX_RANDOMIZE=1 prove -I. -r t/with_resty-events diff --git a/.github/workflows/build_and_test_with_worker_events.yml b/.github/workflows/build_and_test_with_worker_events.yml index 581c9265..73067ac3 100644 --- a/.github/workflows/build_and_test_with_worker_events.yml +++ b/.github/workflows/build_and_test_with_worker_events.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - openresty-version: [1.19.9.1, 1.21.4.1] + openresty-version: [1.21.4.1] steps: - name: Update and install OS dependencies @@ -72,4 +72,4 @@ jobs: run: | eval `luarocks path` eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) - TEST_NGINX_RANDOMIZE=1 prove -I. -r t/with_worker-events + TEST_NGINX_TIMEOUT=4 TEST_NGINX_RANDOMIZE=1 prove -I. -r t/with_worker-events diff --git a/lib/resty/healthcheck.lua b/lib/resty/healthcheck.lua index 6fc84cc9..675ca24c 100644 --- a/lib/resty/healthcheck.lua +++ b/lib/resty/healthcheck.lua @@ -1690,11 +1690,13 @@ function _M.new(opts) end local cur_time = ngx_now() + local is_checked = false for _, checker_obj in pairs(hcs) do if (last_cleanup_check + CLEANUP_INTERVAL) < cur_time then -- clear targets marked for delayed removal locking_target_list(checker_obj, function(target_list) + is_checked = true local removed_targets = {} local index = 1 while index <= #target_list do @@ -1721,8 +1723,6 @@ function _M.new(opts) end end end) - - last_cleanup_check = cur_time end if checker_obj.checks.active.healthy.active and @@ -1741,6 +1741,10 @@ function _M.new(opts) checker_callback(checker_obj, "unhealthy") end end + + if is_checked then + last_cleanup_check = cur_time + end end, }) if not active_check_timer then diff --git a/t/with_resty-events/11-clear.t b/t/with_resty-events/11-clear.t index 6fce9327..c2b436e7 100644 --- a/t/with_resty-events/11-clear.t +++ b/t/with_resty-events/11-clear.t @@ -3,7 +3,7 @@ use Cwd qw(cwd); workers(1); -plan tests => repeat_each() * 27; +plan tests => repeat_each() * 27 + 2; my $pwd = cwd(); $ENV{TEST_NGINX_SERVROOT} = server_root(); @@ -296,3 +296,87 @@ false target not found false target not found + +=== TEST 6: delayed_clear() would clear tgt list when we add two checkers +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local config1 = { + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + } + + local config2 = { + name = "testing2", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + } + + local checker1 = healthcheck.new(config1) + checker1:add_target("127.0.0.1", 10001, nil, true) + checker1:add_target("127.0.0.1", 10002, nil, true) + checker1:add_target("127.0.0.1", 10003, nil, true) + ngx.sleep(0.2) + ngx.say(checker1:get_target_status("127.0.0.1", 10002)) + checker1:delayed_clear(0.2) + + local checker2 = healthcheck.new(config2) + checker2:add_target("127.0.0.1", 10001, nil, true) + checker2:add_target("127.0.0.1", 10002, nil, true) + ngx.sleep(0.2) + ngx.say(checker2:get_target_status("127.0.0.1", 10002)) + checker2:delayed_clear(0.2) + + ngx.sleep(3) -- wait twice the interval + + local status, err = checker1:get_target_status("127.0.0.1", 10001) + if status ~= nil then + ngx.say(status) + else + ngx.say(err) + end + status, err = checker2:get_target_status("127.0.0.1", 10002) + if status ~= nil then + ngx.say(status) + else + ngx.say(err) + end + status, err = checker2:get_target_status("127.0.0.1", 10003) + if status ~= nil then + ngx.say(status) + else + ngx.say(err) + end + } + } +--- request +GET /t +--- response_body +true +true +target not found +target not found +target not found diff --git a/t/with_worker-events/11-clear.t b/t/with_worker-events/11-clear.t index 0ddb02d5..dabafc09 100644 --- a/t/with_worker-events/11-clear.t +++ b/t/with_worker-events/11-clear.t @@ -3,7 +3,7 @@ use Cwd qw(cwd); workers(1); -plan tests => repeat_each() * 27; +plan tests => repeat_each() * 27 + 2; my $pwd = cwd(); @@ -280,3 +280,86 @@ false target not found false target not found + + +=== TEST 6: delayed_clear() would clear tgt list when we add two checkers +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local we = require "resty.worker.events" + assert(we.configure{ shm = "my_worker_events", interval = 0.1 }) + local healthcheck = require("resty.healthcheck") + local config1 = { + name = "testing", + shm_name = "test_shm", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + } + + local config2 = { + name = "testing2", + shm_name = "test_shm", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + } + + local checker1 = healthcheck.new(config1) + checker1:add_target("127.0.0.1", 10001, nil, true) + checker1:add_target("127.0.0.1", 10002, nil, true) + checker1:add_target("127.0.0.1", 10003, nil, true) + ngx.say(checker1:get_target_status("127.0.0.1", 10002)) + checker1:delayed_clear(0.2) + + local checker2 = healthcheck.new(config2) + checker2:add_target("127.0.0.1", 10001, nil, true) + checker2:add_target("127.0.0.1", 10002, nil, true) + ngx.say(checker2:get_target_status("127.0.0.1", 10002)) + checker2:delayed_clear(0.2) + + ngx.sleep(3) -- wait twice the interval + + local status, err = checker1:get_target_status("127.0.0.1", 10001) + if status ~= nil then + ngx.say(status) + else + ngx.say(err) + end + status, err = checker2:get_target_status("127.0.0.1", 10002) + if status ~= nil then + ngx.say(status) + else + ngx.say(err) + end + status, err = checker2:get_target_status("127.0.0.1", 10003) + if status ~= nil then + ngx.say(status) + else + ngx.say(err) + end + } + } +--- request +GET /t +--- response_body +true +true +target not found +target not found +target not found