]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Implement client pending operation limits
authorOndřej Kuzník <okuznik@symas.com>
Thu, 18 Oct 2018 14:59:36 +0000 (15:59 +0100)
committerOndřej Kuzník <okuznik@symas.com>
Tue, 17 Nov 2020 17:58:15 +0000 (17:58 +0000)
doc/man/man5/lloadd.conf.5
servers/lloadd/client.c
servers/lloadd/config.c
servers/lloadd/proto-lload.h

index bf325ada3e6618774b3c216daff3ddf084885e61..49fbfd2b6ec66bc3735081b2b2509e853554c3e3 100644 (file)
@@ -329,6 +329,10 @@ read or this limit is reached when the I/O thread can pick it up again.
 Very high values have a potential to cause some connections to be
 starved in a very high-bandwidth environment. The default is 1000.
 .TP
+.B client_max_pending <integer>
+Will cause the load balancer to limit the number unfinished operations for each
+client connection. The default is 0, unlimited.
+.TP
 .B iotimeout <integer>
 Specify the number of milliseconds to wait before forcibly closing
 a connection with an outstanding write. This allows faster recovery from
index 64f77beba6085ab11b813a2194b699a6167010ad..64a756f78e3351dd1a0d7299c5bd6c60b427ad05 100644 (file)
@@ -24,6 +24,8 @@
 #include "lutil.h"
 #include "lload.h"
 
+long lload_client_max_pending = 0;
+
 lload_c_head clients = LDAP_CIRCLEQ_HEAD_INITIALIZER( clients );
 
 ldap_pvt_thread_mutex_t clients_mutex;
@@ -188,6 +190,7 @@ handle_one_request( LloadConnection *c )
     BerElement *ber;
     LloadOperation *op = NULL;
     RequestHandler handler = NULL;
+    int over_limit = 0;
 
     ber = c->c_currentber;
     c->c_currentber = NULL;
@@ -202,6 +205,10 @@ handle_one_request( LloadConnection *c )
         ber_free( ber, 1 );
         return -1;
     }
+    if ( lload_client_max_pending &&
+            c->c_n_ops_executing >= lload_client_max_pending ) {
+        over_limit = 1;
+    }
     CONNECTION_UNLOCK(c);
 
     switch ( op->o_tag ) {
@@ -223,15 +230,23 @@ handle_one_request( LloadConnection *c )
              * currently in progress */
             return request_abandon( c, op );
         case LDAP_REQ_EXTENDED:
-            handler = request_extended;
-            break;
         default:
             if ( c->c_state == LLOAD_C_BINDING ) {
                 operation_send_reject(
                         op, LDAP_PROTOCOL_ERROR, "bind in progress", 0 );
                 return LDAP_SUCCESS;
             }
-            handler = request_process;
+            if ( over_limit ) {
+                operation_send_reject( op, LDAP_BUSY,
+                        "pending operation limit reached on this connection",
+                        0 );
+                return LDAP_SUCCESS;
+            }
+            if ( op->o_tag == LDAP_REQ_EXTENDED ) {
+                handler = request_extended;
+            } else {
+                handler = request_process;
+            }
             break;
     }
 
index 8d7e504b5f6387a2180c1a39fdd15c9ba17b0b44..e9ea23185077aa9e809f1f64667ade370a315337 100644 (file)
@@ -177,6 +177,7 @@ enum {
     CFG_MAX_PENDING_OPS,
     CFG_MAX_PENDING_CONNS,
     CFG_STARTTLS,
+    CFG_CLIENT_PENDING,
 
     CFG_LAST
 };
@@ -616,6 +617,17 @@ static ConfigTable config_back_cf_table[] = {
             "SINGLE-VALUE )",
         NULL, NULL
     },
+    { "client_max_pending", NULL, 2, 2, 0,
+        ARG_MAGIC|ARG_UINT|CFG_CLIENT_PENDING,
+        &config_generic,
+        "( OLcfgBkAt:13.35 "
+            "NAME 'olcBkLloadClientMaxPending' "
+            "DESC 'Maximum pending operations per client connection' "
+            "EQUALITY integerMatch "
+            "SYNTAX OMsInteger "
+            "SINGLE-VALUE )",
+        NULL, NULL
+    },
 
     /* cn=config only options */
 #ifdef BALANCER_MODULE
@@ -803,6 +815,9 @@ config_generic( ConfigArgs *c )
                 c->value_uint = 1000 * lload_write_timeout->tv_sec +
                         lload_write_timeout->tv_usec / 1000;
                 break;
+            case CFG_CLIENT_PENDING:
+                c->value_uint = lload_client_max_pending;
+                break;
             default:
                 rc = 1;
                 break;
@@ -953,6 +968,9 @@ config_generic( ConfigArgs *c )
         case CFG_MAXBUF_UPSTREAM:
             sockbuf_max_incoming_upstream = c->value_uint;
             break;
+        case CFG_CLIENT_PENDING:
+            lload_client_max_pending = c->value_uint;
+            break;
         default:
             Debug( LDAP_DEBUG_ANY, "%s: unknown CFG_TYPE %d\n",
                     c->log, c->type );
index 21d070313a77c3c3f857bd4d48dfad0bad2fceb8..0ec68b72d39a43bd37ddf9c3a10e972917bec9cf 100644 (file)
@@ -64,6 +64,7 @@ LDAP_SLAPD_F (LloadConnection *) client_init( ber_socket_t s, LloadListener *url
 LDAP_SLAPD_F (void) client_reset( LloadConnection *c );
 LDAP_SLAPD_F (void) client_destroy( LloadConnection *c );
 LDAP_SLAPD_F (void) clients_destroy( int gentle );
+LDAP_SLAPD_V (long) lload_client_max_pending;
 
 /*
  * config.c