mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-28 16:40:37 +00:00
[MEDIUM] listeners: queue proxy-bound listeners at the proxy's
All listeners that are limited by a proxy-specific resource are now queued at the proxy's and not globally. This allows finer-grained wakeups when releasing resource.
This commit is contained in:
parent
08ceb1012b
commit
07687c171e
@ -301,6 +301,7 @@ struct proxy {
|
||||
struct pxcounters be_counters; /* backend statistics counters */
|
||||
struct pxcounters fe_counters; /* frontend statistics counters */
|
||||
|
||||
struct list listener_queue; /* list of the temporarily limited listeners because of lack of a proxy resource */
|
||||
struct stktable table; /* table for storing sticking sessions */
|
||||
|
||||
int grace; /* grace time after stop request */
|
||||
|
@ -1041,6 +1041,7 @@ static void init_new_proxy(struct proxy *p)
|
||||
LIST_INIT(&p->tcp_req.l4_rules);
|
||||
LIST_INIT(&p->req_add);
|
||||
LIST_INIT(&p->rsp_add);
|
||||
LIST_INIT(&p->listener_queue);
|
||||
|
||||
/* Timeouts are defined as -1 */
|
||||
proxy_reset_timeouts(p);
|
||||
|
@ -499,6 +499,10 @@ void maintain_proxies(int *next)
|
||||
goto do_block;
|
||||
}
|
||||
|
||||
/* The proxy is not limited so we can re-enable any waiting listener */
|
||||
if (!LIST_ISEMPTY(&p->listener_queue))
|
||||
dequeue_all_listeners(&p->listener_queue);
|
||||
|
||||
/* OK we have no reason to block, so let's unblock if we were blocking */
|
||||
if (p->state == PR_STIDLE) {
|
||||
for (l = p->listen; l != NULL; l = l->next)
|
||||
|
@ -2096,6 +2096,9 @@ struct task *process_session(struct task *t)
|
||||
if (!LIST_ISEMPTY(&global_listener_queue))
|
||||
dequeue_all_listeners(&global_listener_queue);
|
||||
|
||||
if (!LIST_ISEMPTY(&s->fe->listener_queue))
|
||||
dequeue_all_listeners(&s->fe->listener_queue);
|
||||
|
||||
if (unlikely((global.mode & MODE_DEBUG) &&
|
||||
(!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {
|
||||
int len;
|
||||
|
@ -1192,7 +1192,6 @@ int stream_sock_accept(int fd)
|
||||
int max_accept = global.tune.maxaccept;
|
||||
int cfd;
|
||||
int ret;
|
||||
int loops = 0;
|
||||
|
||||
if (unlikely(l->nbconn >= l->maxconn)) {
|
||||
listener_full(l);
|
||||
@ -1201,15 +1200,31 @@ int stream_sock_accept(int fd)
|
||||
|
||||
if (p && p->fe_sps_lim) {
|
||||
int max = freq_ctr_remain(&p->fe_sess_per_sec, p->fe_sps_lim, 0);
|
||||
|
||||
if (unlikely(!max)) {
|
||||
/* frontend accept rate limit was reached */
|
||||
limit_listener(l, &p->listener_queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_accept > max)
|
||||
max_accept = max;
|
||||
}
|
||||
|
||||
while ((!p || p->feconn < p->maxconn) && actconn < global.maxconn && max_accept--) {
|
||||
while (max_accept--) {
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t laddr = sizeof(addr);
|
||||
|
||||
loops++;
|
||||
if (unlikely(actconn >= global.maxconn)) {
|
||||
limit_listener(l, &global_listener_queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (unlikely(p && p->feconn >= p->maxconn)) {
|
||||
limit_listener(l, &p->listener_queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cfd = accept(fd, (struct sockaddr *)&addr, &laddr);
|
||||
if (unlikely(cfd == -1)) {
|
||||
switch (errno) {
|
||||
@ -1287,10 +1302,6 @@ int stream_sock_accept(int fd)
|
||||
|
||||
} /* end of while (p->feconn < p->maxconn) */
|
||||
|
||||
/* if we did not even enter the loop, we've reached resource limits */
|
||||
if (!loops && max_accept)
|
||||
limit_listener(l, &global_listener_queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user