Expand description
Concurrent-request limiting (limit-conn), ported from APISIX’s
apisix/plugins/limit-conn.
Concurrency is a property of the span between entering and leaving the upstream call, which a single featherbit node cannot observe — a node runs once, at one point in the graph. The behavior is therefore expressed as a pair of nodes sharing one in-flight counter:
- an acquire node placed before
upstream, which increments the counter and rejects when the ceiling is reached, and - a release node placed after
upstream(on both the success and error paths), which decrements the counter.
Both nodes are configured with the same key template (and identical
conn/burst), so crate::traffic::ConnRegistry hands them the same
std::sync::atomic::AtomicI64. This is the same “two phases, one shared
key” shape proxy-rewrite uses for request/response.
§Wiring
┌──────────────────┐ ┌──────────┐ ┌──────────────────┐
listener →│ limit-conn │success →│ upstream │success →│ limit-conn │→ client
│ (phase=acquire) │ │ │ │ (phase=release) │
└──────────────────┘ └──────────┘ └──────────────────┘
│ error │ error ▲
▼ └─────────────────────┘
client.in (release also runs on the error path
(503 rejection) so the counter always decrements)The acquire node’s error port goes to client.in: an over-limit request
short-circuits straight to the client with the rejection response. The
release node must sit on every path out of upstream (success and error)
so a failed upstream call still frees the slot.
Structs§
- Limit
Conn Plugin - One node of a
limit-connacquire/release pair.
Enums§
- Role 🔒
- Which half of the pair this node is.
Functions§
- json_
string 🔒 - Minimal JSON string escaping for the rejection message.