changeset 21033:574338c4e346

lib-http: client: If a peer object is no longer linked to a queue, don't close it until all connections are inactive. The peer object is canceled, rather than closed. Which means that any newly started and idle connections are closed immediately. Requests may be pending though. This is only relevant when hosts/queues are removed at some point. This is a preparational change for having a maximum lifetime on hosts/queues, in which case this becomes a possibility.
author Stephan Bosch <stephan@dovecot.fi>
date Wed, 14 Sep 2016 21:37:38 +0200
parents 44c8ad3de36a
children 3c1664c8f8c5
files src/lib-http/http-client-peer.c
diffstat 1 files changed, 21 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-http/http-client-peer.c	Wed Sep 14 01:37:05 2016 +0200
+++ b/src/lib-http/http-client-peer.c	Wed Sep 14 21:37:38 2016 +0200
@@ -183,6 +183,23 @@
 	return FALSE;
 }
 
+static void
+http_client_peer_cancel(struct http_client_peer *peer)
+{
+	struct http_client_connection **conn;
+	ARRAY_TYPE(http_client_connection) conns;
+
+	http_client_peer_debug(peer, "Peer cancel");
+
+	/* make a copy of the connection array; freed connections modify it */
+	t_array_init(&conns, array_count(&peer->conns));
+	array_copy(&conns.arr, 0, &peer->conns.arr, 0, array_count(&peer->conns));
+	array_foreach_modifiable(&conns, conn) {
+		if (!http_client_connection_is_active(*conn))
+			http_client_connection_close(conn);
+	}
+}
+
 static unsigned int
 http_client_peer_requests_pending(struct http_client_peer *peer,
 				  unsigned int *num_urgent_r)
@@ -236,13 +253,13 @@
 	/* FIXME: limit the number of requests handled in one run to prevent
 	   I/O starvation. */
 
-	/* disconnect if we're not linked to any queue anymore */
+	/* disconnect pending connections if we're not linked to any queue
+	   anymore */
 	if (array_count(&peer->queues) == 0) {
-		i_assert(peer->to_backoff != NULL);
 		http_client_peer_debug(peer,
-			"Peer no longer used; will now disconnect "
+			"Peer no longer used; will now cancel pending connections "
 			"(%u connections exist)", array_count(&peer->conns));
-		http_client_peer_close(&peer);
+		http_client_peer_cancel(peer);
 		return;
 	}