fix(limit-conn): use parent resource key for consumer isolation - #13600
fix(limit-conn): use parent resource key for consumer isolation#13600DanielWu-star wants to merge 4 commits into
Conversation
Previously, when limit-conn was configured at the consumer level, connection limits were applied per-route instead of globally per consumer. This occurred because the key generation concatenated ctx.conf_type and ctx.conf_version, which included route-specific information. This commit fixes the issue by using conf._meta.parent.resource_key for key generation, consistent with the same fix already applied to limit-req (apache#13019) and limit-count plugins. Now consumer-level connection limits are properly shared across all routes accessed by the same consumer. Fixes apache#13584 Changes: - Added gen_limit_key() function using parent.resource_key approach - Replaced key = key .. ctx.conf_type .. ctx.conf_version with gen_limit_key(conf, ctx, key) in run_limit_conn() - Updated test cases to match new key format - Added test cases (TEST 35-42) verifying consumer isolation across multiple routes
The expected keys were written as `routes/1`, but `resource_key` is the full etcd key, so the assertions in limit-conn.t never matched; limit-conn-redis.t still carried the pre-fix format. `error_log_like` is not a test-nginx section either, so those two blocks were never evaluated. The consumer-level blocks are moved to t/plugin/limit-conn-shared-counter.t and rewritten to fire the requests in parallel: limit-conn counts concurrent connections and releases the counter in the log phase, so the pipelined requests copied from the limit-req test could never hit the limit.
|
I pushed two commits to this branch (merged master to clear the conflict, then fixed the tests). The plugin change itself is unchanged apart from the conflict resolution. Conflict: master added Tests — none of the assertions this PR touched were actually checking the fix:
Those blocks are replaced by Locally One thing worth adding to the PR description: the cross-instance half of #13584. |
Every other failure path in run_limit_conn() falls back to allow_degradation; the new nil-key branch was the only one that always returned 500. Also drop the now misleading `ver:` log line, since ctx.conf_version no longer takes part in the key. Tests: - limit-conn-shared-counter.t keys both consumers on remote_addr, so they resolve to the same value and only the parent resource_key keeps them apart. TEST 5 previously passed with or without the fix; now it fails without it. - The file deletes its routes and consumers again. /apisix/routes/2 (uri /limit_conn2) leaked into t/plugin/workflow3.t, which expects that uri to 404 and got 401 from the leftover key-auth route. - workflow3.t asserts both _vid suffixes: the two workflow rules carry identical limit-conn confs on one route, so _vid is all that separates them. - stream-plugin/limit-conn.t asserts the stream_route key shape, pinning the fact that stream routes go through the same router.lua filter.
|
Second round, after a review pass. Pushed One of these would have broken CI. TEST 5 was not testing what it claimed. Both consumers were keyed on
Two invariants pinned.
Also dropped the One more thing for the description, beyond the consumer case: service-level Out of scope, but found while checking this — two pre-existing issues that also affect
|
Previously, when limit-conn was configured at the consumer level, connection limits were applied per-route instead of globally per consumer. This occurred because the key generation concatenated ctx.conf_type and ctx.conf_version, which included route-specific information.
This commit fixes the issue by using conf._meta.parent.resource_key for key generation, consistent with the same fix already applied to limit-req (#13019) and limit-count plugins. Now consumer-level connection limits are properly shared across all routes accessed by the same consumer.
Changes:
Description
Which issue(s) this PR fixes:
Fixes #13584
Checklist