]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Implement backend retry timeouts
authorOndřej Kuzník <ondra@mistotebe.net>
Wed, 12 Apr 2017 15:02:35 +0000 (16:02 +0100)
committerOndřej Kuzník <okuznik@symas.com>
Tue, 17 Nov 2020 17:55:46 +0000 (17:55 +0000)
servers/lloadd/backend.c
servers/lloadd/daemon.c
servers/lloadd/proto-slap.h

index d0d9b85e2c56e339843818d09b05c536ebb19302..89123f9c76e86d065a6d9d9dcaa07199d9daca12 100644 (file)
@@ -134,34 +134,57 @@ backend_retry( Backend *b )
     int rc, requested;
 
     ldap_pvt_thread_mutex_lock( &b->b_mutex );
-    /* TODO: timeout regime */
 
     requested = b->b_numconns;
     if ( !(lload_features & LLOAD_FEATURE_VC) ) {
         requested += b->b_numbindconns;
     }
     if ( b->b_active + b->b_bindavail + b->b_opening < requested ) {
-        b->b_opening++;
-        rc = ldap_pvt_thread_pool_submit(
-                &connection_pool, backend_connect, b );
-        /* TODO check we're not shutting down */
-        if ( rc ) {
-            ldap_pvt_thread_mutex_unlock( &b->b_mutex );
-            backend_connect( NULL, b );
-            return;
+        if ( b->b_opening > 0 || b->b_failed > 0 ) {
+            if ( !event_pending( b->b_retry_event, EV_TIMEOUT, NULL ) ) {
+                Debug( LDAP_DEBUG_CONNS, "backend_retry: "
+                        "scheduling a retry in %d ms\n",
+                        b->b_retry_timeout );
+                b->b_opening++;
+                event_add( b->b_retry_event, &b->b_retry_tv );
+                ldap_pvt_thread_mutex_unlock( &b->b_mutex );
+                return;
+            } else {
+                Debug( LDAP_DEBUG_CONNS, "backend_retry: "
+                        "retry already scheduled\n" );
+            }
+        } else {
+            Debug( LDAP_DEBUG_CONNS, "backend_retry: "
+                    "scheduling re-connection straight away\n" );
+            b->b_opening++;
+            rc = ldap_pvt_thread_pool_submit(
+                    &connection_pool, backend_connect_task, b );
+            /* TODO check we're not shutting down */
+            if ( rc ) {
+                ldap_pvt_thread_mutex_unlock( &b->b_mutex );
+                backend_connect( -1, 0, b );
+                return;
+            }
         }
+    } else {
+        Debug( LDAP_DEBUG_CONNS, "backend_retry: "
+                "no more connections needed for this backend\n" );
     }
     ldap_pvt_thread_mutex_unlock( &b->b_mutex );
 }
 
-void *
-backend_connect( void *ctx, void *arg )
+void
+backend_connect( evutil_socket_t s, short what, void *arg )
 {
     struct evutil_addrinfo hints = {};
     Backend *b = arg;
     char *hostname;
 
     ldap_pvt_thread_mutex_lock( &b->b_mutex );
+    Debug( LDAP_DEBUG_CONNS, "backend_connect: "
+            "attempting connection to %s\n",
+            b->b_host );
+
 #ifdef LDAP_PF_LOCAL
     if ( b->b_proto == LDAP_PROTO_IPC ) {
         struct sockaddr_un addr;
@@ -200,7 +223,7 @@ backend_connect( void *ctx, void *arg )
         b->b_failed = 0;
         ldap_pvt_thread_mutex_unlock( &b->b_mutex );
         backend_retry( b );
-        return NULL;
+        return;
     }
 #endif /* LDAP_PF_LOCAL */
 
@@ -213,12 +236,18 @@ backend_connect( void *ctx, void *arg )
     ldap_pvt_thread_mutex_unlock( &b->b_mutex );
 
     evdns_getaddrinfo( dnsbase, hostname, NULL, &hints, upstream_name_cb, b );
-    return NULL;
+    return;
 
 fail:
     b->b_opening--;
     b->b_failed++;
     ldap_pvt_thread_mutex_unlock( &b->b_mutex );
     backend_retry( b );
-    return (void *)-1;
+}
+
+void *
+backend_connect_task( void *ctx, void *arg )
+{
+    backend_connect( -1, 0, arg );
+    return NULL;
 }
index fbf8621500f9975c51a341ae6d008b20bd07b7cb..1956ba5f7e3f28fab31f2c92a5d50691ec137b1a 100644 (file)
@@ -1300,8 +1300,23 @@ slapd_daemon( struct event_base *daemon_base )
     }
 
     LDAP_STAILQ_FOREACH ( b, &backend, b_next ) {
+        struct event *retry_event =
+                evtimer_new( daemon_base, backend_connect, b );
+
+        if ( !retry_event ) {
+            Debug( LDAP_DEBUG_ANY, "lloadd: "
+                    "failed to allocate retry event\n" );
+            return -1;
+        }
+        b->b_retry_event = retry_event;
         b->b_opening++;
-        ldap_pvt_thread_pool_submit( &connection_pool, backend_connect, b );
+
+        rc = ldap_pvt_thread_pool_submit(
+                &connection_pool, backend_connect_task, b );
+        if ( rc ) {
+            Debug( LDAP_DEBUG_ANY, "failed to schedule backend connection task (%d)\n", rc );
+            return rc;
+        }
     }
 
     lloadd_inited = 1;
index 6c14fd8ddfe5e870274afc5456c89e72bdd03e74..16af23fc832ee6cb5f125c57f1346610936dd378 100644 (file)
@@ -40,7 +40,8 @@ struct config_reply_s; /* config.h */
  * backend.c
  */
 
-LDAP_SLAPD_F (void *) backend_connect( void *ctx, void *arg );
+LDAP_SLAPD_F (void) backend_connect( evutil_socket_t s, short what, void *arg );
+LDAP_SLAPD_F (void *) backend_connect_task( void *ctx, void *arg );
 LDAP_SLAPD_F (void) backend_retry( Backend *b );
 LDAP_SLAPD_F (Connection *) backend_select( Operation *op );