diff -ru haproxy-1.3.15.2/doc/configuration.txt ha/doc/configuration.txt --- haproxy-1.3.15.2/doc/configuration.txt 2008-06-22 03:59:05.000000000 +0800 +++ ha/doc/configuration.txt 2008-09-04 00:26:17.000000000 +0800 @@ -3586,6 +3586,28 @@ to handle some load. It is useful to report a failure when combined with "monitor fail". +connslots +connslots(backend) + The basic idea here is to be able to measure the number of connection "slots" + still available (connection, + queue) - so that anything beyond that (intended + usage; see "use_backend" keyword) can be redirected to a different backend. + + 'connslots' = number of available server connection slots, + number of available + server queue slots. + + *Note that while "dst_conn" may be used, "connslots" comes in especially useful + when you have a case of traffic going to one single ip, splitting into multiple + backends (perhaps using acls to do name-based load balancing) - and you want to + be able to differentiate between different backends, and their "connslots" + available. Also, whereas "nbsrv" only measures servers that are actually *down*, + this acl is more fine-grained - and looks into the number of conn slots available + as well. + + *OTHER CAVEATS AND NOTES: at this point in time, the code does not take care of + dynamic connections. Also, if any of the server maxconn, or maxqueue is 0, then + this acl clearly does not make sense - in which case the value returned will be -1. + + 2.3.5.2) Matching at Layer 7 ---------------------------- diff -ru haproxy-1.3.15.2/src/backend.c ha/src/backend.c --- haproxy-1.3.15.2/src/backend.c 2008-06-22 03:59:05.000000000 +0800 +++ ha/src/backend.c 2008-09-03 23:47:48.000000000 +0800 @@ -2115,9 +2115,40 @@ } +/* set test->i to the number of enabled servers on the proxy */ +static int +acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir, + struct acl_expr *expr, struct acl_test *test) +{ + struct server *iterator; + test->flags = ACL_TEST_F_VOL_TEST; + if (expr->arg_len) { + /* another proxy was designated, we must look for it */ + for (px = proxy; px; px = px->next) + if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str)) + break; + } + if (!px) + return 0; + + test->i = 0; + iterator = px->srv; + while (iterator) { + if ((iterator->state & 1) == 0) { iterator = iterator->next; continue; } + if (iterator->maxconn == 0 || iterator->maxqueue == 0) { test->i = -1; return 1; } + + test->i += (iterator->maxconn - iterator->cur_ses) + (iterator->maxqueue - iterator->nbpend); + iterator = iterator->next; + } + + return 1; +} + + /* Note: must not be declared as its list will be overwritten */ static struct acl_kw_list acl_kws = {{ },{ { "nbsrv", acl_parse_int, acl_fetch_nbsrv, acl_match_int }, + { "connlots", acl_parse_int, acl_fetch_connslots, acl_match_int }, { NULL, NULL, NULL, NULL }, }};