diff options
author | Willy Tarreau <w@1wt.eu> | 2020-09-24 07:27:06 +0200 |
---|---|---|
committer | Willy Tarreau <w@1wt.eu> | 2020-10-07 18:44:08 +0200 |
commit | 7cf76b8423df6d3ad1019b82412085f5b0924108 (patch) | |
tree | 2822ca349d25b713f14f678fe7bf400e1b8ce6d5 | |
parent | b6a486166da3347dffc83d8d7ecada88a73348ec (diff) | |
download | haproxy-7cf76b8423df6d3ad1019b82412085f5b0924108.tar.gz |
MINOR: proxy: maintain per-state counters of listeners
The proxy state tries to be synthetic but that doesn't work well with
many listeners, especially for transition phases or after a failed
pause/resume.
In order to address this, we'll instead rely on counters of listeners in
a given state for the 3 major states (ready, paused, listen) and a total
counter. We'll now be able to determine a proxy's state by comparing these
counters only.
-rw-r--r-- | include/haproxy/proxy-t.h | 4 | ||||
-rw-r--r-- | src/listener.c | 48 |
2 files changed, 51 insertions, 1 deletions
diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index 2680fbffa..16fee4a2e 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -395,6 +395,10 @@ struct proxy { int uuid; /* universally unique proxy ID, used for SNMP */ unsigned int backlog; /* force the frontend's listen backlog */ unsigned long bind_proc; /* bitmask of processes using this proxy */ + unsigned int li_all; /* total number of listeners attached to this proxy */ + unsigned int li_paused; /* total number of listeners paused (LI_PAUSED) */ + unsigned int li_bound; /* total number of listeners ready (LI_LISTEN) */ + unsigned int li_ready; /* total number of listeners ready (>=LI_READY) */ /* warning: these structs are huge, keep them at the bottom */ struct sockaddr_storage dispatch_addr; /* the default address to connect to */ diff --git a/src/listener.c b/src/listener.c index 1ad017db8..c4ee3c319 100644 --- a/src/listener.c +++ b/src/listener.c @@ -218,9 +218,55 @@ REGISTER_CONFIG_POSTPARSER("multi-threaded accept queue", accept_queue_init); #endif // USE_THREAD -/* adjust the listener's state */ +/* adjust the listener's state and its proxy's listener counters if needed. + * It must be called under the listener's lock, but uses atomic ops to change + * the proxy's counters so that the proxy lock is not needed. + */ void listener_set_state(struct listener *l, enum li_state st) { + struct proxy *px = l->bind_conf->frontend; + + if (px) { + /* from state */ + switch (l->state) { + case LI_NEW: /* first call */ + _HA_ATOMIC_ADD(&px->li_all, 1); + break; + case LI_INIT: + case LI_ASSIGNED: + break; + case LI_PAUSED: + _HA_ATOMIC_SUB(&px->li_paused, 1); + break; + case LI_LISTEN: + _HA_ATOMIC_SUB(&px->li_bound, 1); + break; + case LI_READY: + case LI_FULL: + case LI_LIMITED: + _HA_ATOMIC_SUB(&px->li_ready, 1); + break; + } + + /* to state */ + switch (st) { + case LI_NEW: + case LI_INIT: + case LI_ASSIGNED: + break; + case LI_PAUSED: + _HA_ATOMIC_ADD(&px->li_paused, 1); + break; + case LI_LISTEN: + _HA_ATOMIC_ADD(&px->li_bound, 1); + break; + case LI_READY: + case LI_FULL: + case LI_LIMITED: + _HA_ATOMIC_ADD(&px->li_ready, 1); + break; + } + } l->state = st; } |