]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: client: peer: Maintain a list of connections pending on behalf of a peer.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Thu, 6 Sep 2018 01:33:59 +0000 (03:33 +0200)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Fri, 7 Sep 2018 06:18:56 +0000 (09:18 +0300)
Before, pending connections were only listed in the peer pool.

src/lib-http/http-client-connection.c
src/lib-http/http-client-peer.c
src/lib-http/http-client-private.h

index abb7bb922339ee50c607d21cf2c6c482db1f431b..4411db7b89ed5caa396638cf6ea6b9d100af7d29 100644 (file)
@@ -48,11 +48,12 @@ http_client_connection_unref_request(struct http_client_connection *conn,
 static void
 http_client_connection_unlist_pending(struct http_client_connection *conn)
 {
+       struct http_client_peer *peer = conn->peer;
        struct http_client_peer_pool *ppool = conn->ppool;
        ARRAY_TYPE(http_client_connection) *conn_arr;
        struct http_client_connection *const *conn_idx;
 
-       /* remove from pending list */
+       /* remove from pending lists */
 
        conn_arr = &ppool->pending_conns;
        array_foreach(conn_arr, conn_idx) {
@@ -62,6 +63,18 @@ http_client_connection_unlist_pending(struct http_client_connection *conn)
                        break;
                }
        }
+
+       if (peer == NULL)
+               return;
+
+       conn_arr = &peer->pending_conns;
+       array_foreach(conn_arr, conn_idx) {
+               if (*conn_idx == conn) {
+                       array_delete(conn_arr,
+                                    array_foreach_idx(conn_arr, conn_idx), 1);
+                       break;
+               }
+       }
 }
 
 static inline void
@@ -371,9 +384,16 @@ http_client_connection_detach_peer(struct http_client_connection *conn)
                        break;
                }
        }
-
        i_assert(found);
 
+       conn_arr = &peer->pending_conns;
+       array_foreach(conn_arr, conn_idx) {
+               if (*conn_idx == conn) {
+                       array_delete(conn_arr, array_foreach_idx(conn_arr, conn_idx), 1);
+                       break;
+               }
+       }
+
        conn->peer = NULL;
        e_debug(conn->event, "Detached peer");
 
@@ -1703,6 +1723,7 @@ http_client_connection_create(struct http_client_peer *peer)
 
        array_append(&ppool->pending_conns, &conn, 1);
        array_append(&ppool->conns, &conn, 1);
+       array_append(&peer->pending_conns, &conn, 1);
        array_append(&peer->conns, &conn, 1);
 
        http_client_peer_pool_ref(ppool);
index afa71e94ecb0cf2f0ed831876743f92e8c49fe2f..3116fe345661e6719d857b36f7e3d9bd0d609c50 100644 (file)
@@ -569,6 +569,7 @@ http_client_peer_create(struct http_client *client,
 
        i_array_init(&peer->queues, 16);
        i_array_init(&peer->conns, 16);
+       i_array_init(&peer->pending_conns, 16);
 
        DLLIST_PREPEND_FULL
                (&client->peers_list, peer, client_prev, client_next);
@@ -624,6 +625,7 @@ http_client_peer_disconnect(struct http_client_peer *peer)
        array_foreach_modifiable(&conns, conn)
                http_client_connection_lost_peer(*conn);
        i_assert(array_count(&peer->conns) == 0);
+       array_clear(&peer->pending_conns);
 
        timeout_remove(&peer->to_req_handling);
 
@@ -661,6 +663,7 @@ bool http_client_peer_unref(struct http_client_peer **_peer)
 
        event_unref(&peer->event);
        array_free(&peer->conns);
+       array_free(&peer->pending_conns);
        array_free(&peer->queues);
        i_free(peer);
 
@@ -838,6 +841,7 @@ http_client_peer_cancel(struct http_client_peer *peer)
                if (!http_client_connection_is_active(*conn))
                        http_client_connection_close(conn);
        }
+       i_assert(array_count(&peer->pending_conns) == 0);
 }
 
 static unsigned int
@@ -926,7 +930,7 @@ http_client_peer_handle_requests_real(struct http_client_peer *peer)
                bool conn_lost = FALSE;
 
                array_clear(&conns_avail);
-               connecting = closing = idle = 0;
+               closing = idle = 0;
 
                /* gather connection statistics */
                array_foreach(&peer->conns, conn_idx) {
@@ -962,8 +966,6 @@ http_client_peer_handle_requests_real(struct http_client_peer *peer)
                        /* count the number of connecting and closing connections */
                        if (conn->closing)
                                closing++;
-                       else if (!conn->connected)
-                               connecting++;
                }
 
                if (conn_lost) {
@@ -1020,6 +1022,7 @@ http_client_peer_handle_requests_real(struct http_client_peer *peer)
                return;
 
        i_assert(idle == 0);
+       connecting = array_count(&peer->pending_conns);
 
        /* determine how many new connections we can set up */
        if (pshared->last_failure.tv_sec > 0 && working_conn_count > 0 &&
@@ -1315,16 +1318,7 @@ http_client_peer_active_connections(struct http_client_peer *peer)
 unsigned int
 http_client_peer_pending_connections(struct http_client_peer *peer)
 {
-       struct http_client_connection *const *conn_idx;
-       unsigned int pending = 0;
-
-       /* find idle connections */
-       array_foreach(&peer->conns, conn_idx) {
-               if (!(*conn_idx)->closing && !(*conn_idx)->connected)
-                       pending++;
-       }
-
-       return pending;
+       return array_count(&peer->pending_conns);
 }
 
 void http_client_peer_switch_ioloop(struct http_client_peer *peer)
index 130807698cc1bfd8252e31b794956e4446bf620f..38bc2a63146340cbec5d104943be69bfa1f0a41b 100644 (file)
@@ -274,6 +274,8 @@ struct http_client_peer {
 
        /* active connections to this peer */
        ARRAY_TYPE(http_client_connection) conns;
+       /* pending connections (not ready connecting) */
+       ARRAY_TYPE(http_client_connection) pending_conns;
 
        /* zero time-out for consolidating request handling */
        struct timeout *to_req_handling;