dovecot-2.2: lib-http: Simplify error handling by delaying conne...

dovecot at dovecot.org dovecot at dovecot.org
Thu Apr 4 14:20:48 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/1bd5972eac0a
changeset: 16148:1bd5972eac0a
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Apr 04 14:18:38 2013 +0300
description:
lib-http: Simplify error handling by delaying connect() failures.

diffstat:

 src/lib-http/http-client-connection.c |  30 ++++++++++++-----------
 src/lib-http/http-client-host.c       |  44 ++++++++++++++--------------------
 src/lib-http/http-client-peer.c       |  27 +++------------------
 src/lib-http/http-client-private.h    |   1 +
 4 files changed, 39 insertions(+), 63 deletions(-)

diffs (197 lines):

diff -r b4927eea33fd -r 1bd5972eac0a src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c	Thu Apr 04 14:11:10 2013 +0300
+++ b/src/lib-http/http-client-connection.c	Thu Apr 04 14:18:38 2013 +0300
@@ -731,7 +731,8 @@
 		(struct http_client_connection *)_conn;
 
 	if (!success) {
-		http_client_connection_error(conn, "Connect failed: %m");
+		http_client_connection_error(conn, "connect(%s) failed: %m",
+					     _conn->name);
 		http_client_peer_connection_failure(conn->peer);
 
 	} else {
@@ -764,16 +765,21 @@
 		(&http_client_connection_set, &http_client_connection_vfuncs);
 }
 
-static int http_client_connection_connect(struct http_client_connection *conn)
+static void
+http_client_connection_delayed_connect_error(struct http_client_connection *conn)
 {
-	if (conn->conn.fd_in == -1) {
-		if (connection_client_connect(&conn->conn) < 0) {
-			http_client_connection_error(conn, "Could not connect");
-			return -1;
-		}
+	timeout_remove(&conn->to_input);
+	errno = conn->connect_errno;
+	http_client_connection_connected(&conn->conn, FALSE);
+}
+
+static void http_client_connection_connect(struct http_client_connection *conn)
+{
+	if (connection_client_connect(&conn->conn) < 0) {
+		conn->connect_errno = errno;
+		conn->to_input = timeout_add_short(0,
+			http_client_connection_delayed_connect_error, conn);
 	}
-
-	return 0;
 }
 
 struct http_client_connection *
@@ -790,11 +796,7 @@
 
 	connection_init_client_ip
 		(peer->client->conn_list, &conn->conn, &peer->addr.ip, peer->addr.port);
-
-	if (http_client_connection_connect(conn) < 0) {
-		http_client_connection_unref(&conn);
-		return NULL;
-	}
+	http_client_connection_connect(conn);
 
 	conn->id = id++;
 	array_append(&peer->conns, &conn, 1);
diff -r b4927eea33fd -r 1bd5972eac0a src/lib-http/http-client-host.c
--- a/src/lib-http/http-client-host.c	Thu Apr 04 14:11:10 2013 +0300
+++ b/src/lib-http/http-client-host.c	Thu Apr 04 14:18:38 2013 +0300
@@ -118,33 +118,8 @@
 {
 	struct http_client_peer *peer = NULL;
 	struct http_client_peer_addr addr;
-	const char *error;
 
-	if (hport->ssl && host->client->ssl_ctx == NULL) {
-		if (http_client_init_ssl_ctx(host->client, &error) < 0) {
-			http_client_host_port_error(hport,
-				HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, error);
-			if (host->client->ioloop != NULL)
-				io_loop_stop(host->client->ioloop);
-			return;
-		}
-	}
-
-	while (hport->ips_connect_idx < host->ips_count) {
-		addr.ip = host->ips[hport->ips_connect_idx];
-		addr.port = hport->port;
-		addr.ssl = hport->ssl;
-
-		http_client_host_debug(host, "Setting up connection to %s:%u (ssl=%s)", 
-			net_ip2addr(&addr.ip), addr.port, (addr.ssl ? "yes" : "no"));
-
-		if ((peer=http_client_peer_get(host->client, &addr)) != NULL)
-			break;
-
-		hport->ips_connect_idx++;
-	}
-
-	if (peer == NULL) {
+	if (hport->ips_connect_idx == host->ips_count) {
 		/* all IPs failed, but retry all of them again on the
 		   next request. */
 		hport->ips_connect_idx = 0;
@@ -155,6 +130,14 @@
 		return;
 	}
 
+	addr.ip = host->ips[hport->ips_connect_idx];
+	addr.port = hport->port;
+	addr.ssl = hport->ssl;
+
+	http_client_host_debug(host, "Setting up connection to %s:%u (ssl=%s)",
+		net_ip2addr(&addr.ip), addr.port, (addr.ssl ? "yes" : "no"));
+
+	peer = http_client_peer_get(host->client, &addr);
 	http_client_peer_add_host(peer, host);
 }
 
@@ -293,9 +276,18 @@
 	struct http_client_request *req)
 {
 	struct http_client_host_port *hport;
+	const char *error;
 
 	req->host = host;
 
+	if (req->ssl && host->client->ssl_ctx == NULL) {
+		if (http_client_init_ssl_ctx(host->client, &error) < 0) {
+			http_client_request_error(req,
+				HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, error);
+			return;
+		}
+	}
+
 	/* add request to host (grouped by tcp port) */
 	hport = http_client_host_port_init(host, req->port, req->ssl);
 	if (req->urgent)
diff -r b4927eea33fd -r 1bd5972eac0a src/lib-http/http-client-peer.c
--- a/src/lib-http/http-client-peer.c	Thu Apr 04 14:11:10 2013 +0300
+++ b/src/lib-http/http-client-peer.c	Thu Apr 04 14:18:38 2013 +0300
@@ -78,23 +78,15 @@
 	return (*host)->name;
 }
 
-static int
+static void
 http_client_peer_connect(struct http_client_peer *peer, unsigned int count)
 {
-	struct http_client_connection *conn;
 	unsigned int i;
 
 	for (i = 0; i < count; i++) {
 		http_client_peer_debug(peer, "Making new connection %u of %u", i+1, count);
-
-		conn = http_client_connection_create(peer);
-		if (conn == NULL) {
-			http_client_peer_debug(peer, "Failed to make new connection");
-			return -1;
-		}
+		(void)http_client_connection_create(peer);
 	}
-
-	return 0;
 }
 
 static unsigned int
@@ -173,13 +165,7 @@
 	} else {
 		new_connections = (num_urgent > connecting ? num_urgent - connecting : 0);
 	}
-	if (http_client_peer_connect(peer, new_connections) < 0) {
-		/* connection failed */
-		if (conn == NULL)
-			return FALSE;
-		/* pipeline it on the least busy connection we found */
-		return http_client_connection_next_request(conn);
-	}
+	http_client_peer_connect(peer, new_connections);
 
 	/* now we wait until it is connected */
 	return FALSE;
@@ -209,12 +195,7 @@
 	DLLIST_PREPEND(&client->peers_list, peer);
 
 	http_client_peer_debug(peer, "Peer created");
-
-	if (http_client_peer_connect(peer, 1) < 0) {
-		http_client_peer_free(&peer);
-		return NULL;
-	}
-
+	http_client_peer_connect(peer, 1);
 	return peer;
 }
 
diff -r b4927eea33fd -r 1bd5972eac0a src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h	Thu Apr 04 14:11:10 2013 +0300
+++ b/src/lib-http/http-client-private.h	Thu Apr 04 14:18:38 2013 +0300
@@ -133,6 +133,7 @@
 	const char *label;
 
 	unsigned int id; // DEBUG: identify parallel connections
+	int connect_errno;
 
 	struct ssl_iostream *ssl_iostream;
 	struct http_response_parser *http_parser;


More information about the dovecot-cvs mailing list