dovecot-2.1: redis: Fixed connection handling.

dovecot at dovecot.org dovecot at dovecot.org
Sun Jul 8 09:18:56 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/64725ff9c297
changeset: 14609:64725ff9c297
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jul 08 09:18:46 2012 +0300
description:
redis: Fixed connection handling.

diffstat:

 src/lib-dict/dict-redis.c |  44 ++++++++++++++++++++++++++++++++------------
 src/lib/connection.c      |  16 ++++++----------
 src/lib/connection.h      |   1 +
 3 files changed, 39 insertions(+), 22 deletions(-)

diffs (163 lines):

diff -r 211fbc872ed4 -r 64725ff9c297 src/lib-dict/dict-redis.c
--- a/src/lib-dict/dict-redis.c	Sun Jul 08 09:00:57 2012 +0300
+++ b/src/lib-dict/dict-redis.c	Sun Jul 08 09:18:46 2012 +0300
@@ -28,11 +28,7 @@
 
 	struct ioloop *ioloop;
 	struct redis_connection conn;
-};
-
-struct redis_dict_iterate_context {
-	struct dict_iterate_context ctx;
-	struct redis_connection *conn;
+	bool connected;
 };
 
 static struct connection_list *redis_connections;
@@ -41,6 +37,7 @@
 {
 	struct redis_connection *conn = (struct redis_connection *)_conn;
 
+	conn->dict->connected = FALSE;
 	connection_disconnect(_conn);
 	if (conn->dict->ioloop != NULL)
 		io_loop_stop(conn->dict->ioloop);
@@ -101,6 +98,20 @@
 	}
 }
 
+static void redis_conn_connected(struct connection *_conn)
+{
+	struct redis_connection *conn = (struct redis_connection *)_conn;
+
+	if ((errno = net_geterror(_conn->fd_in)) != 0) {
+		i_error("redis: connect(%s, %u) failed: %m",
+			net_ip2addr(&conn->dict->ip), conn->dict->port);
+	} else {
+		conn->dict->connected = TRUE;
+	}
+	if (conn->dict->ioloop != NULL)
+		io_loop_stop(conn->dict->ioloop);
+}
+
 static const struct connection_settings redis_conn_set = {
 	.input_max_size = (size_t)-1,
 	.output_max_size = (size_t)-1,
@@ -109,7 +120,8 @@
 
 static const struct connection_vfuncs redis_conn_vfuncs = {
 	.destroy = redis_conn_destroy,
-	.input = redis_conn_input
+	.input = redis_conn_input,
+	.connected = redis_conn_connected
 };
 
 static struct dict *
@@ -171,7 +183,8 @@
 
 static void redis_dict_lookup_timeout(struct redis_dict *dict)
 {
-	i_error("redis: Lookup timed out in %u secs", dict->timeout_msecs);
+	i_error("redis: Lookup timed out in %u.%03u secs",
+		dict->timeout_msecs/1000, dict->timeout_msecs%1000);
 	io_loop_stop(dict->ioloop);
 }
 
@@ -203,12 +216,19 @@
 	} else {
 		to = timeout_add(dict->timeout_msecs,
 				 redis_dict_lookup_timeout, dict);
-		cmd = t_strdup_printf("*2\r\n$3\r\nGET\r\n$%d\r\n%s\r\n",
-				      (int)strlen(key), key);
-		o_stream_send_str(dict->conn.conn.output, cmd);
+		if (!dict->connected) {
+			/* wait for connection */
+			io_loop_run(dict->ioloop);
+		}
 
-		str_truncate(dict->conn.last_reply, 0);
-		io_loop_run(dict->ioloop);
+		if (dict->connected) {
+			cmd = t_strdup_printf("*2\r\n$3\r\nGET\r\n$%d\r\n%s\r\n",
+					      (int)strlen(key), key);
+			o_stream_send_str(dict->conn.conn.output, cmd);
+
+			str_truncate(dict->conn.last_reply, 0);
+			io_loop_run(dict->ioloop);
+		}
 		timeout_remove(&to);
 	}
 
diff -r 211fbc872ed4 -r 64725ff9c297 src/lib/connection.c
--- a/src/lib/connection.c	Sun Jul 08 09:00:57 2012 +0300
+++ b/src/lib/connection.c	Sun Jul 08 09:18:46 2012 +0300
@@ -105,6 +105,7 @@
 {
 	const struct connection_settings *set = &conn->list->set;
 
+	i_assert(conn->io == NULL);
 	i_assert(conn->input == NULL);
 	i_assert(conn->output == NULL);
 	i_assert(conn->to == NULL);
@@ -119,6 +120,7 @@
 		conn->output = o_stream_create_fd(conn->fd_out,
 						  set->output_max_size, FALSE);
 	}
+	conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn);
 	if (set->input_idle_timeout_secs != 0) {
 		conn->to = timeout_add(set->input_idle_timeout_secs*1000,
 				       connection_idle_timeout, conn);
@@ -128,12 +130,8 @@
 			"VERSION\t%s\t%u\t%u\n", set->service_name_out,
 			set->major_version, set->minor_version));
 	}
-}
-
-static void connection_init_io(struct connection *conn)
-{
-	i_assert(conn->io == NULL);
-	conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn);
+	if (conn->list->v.connected != NULL)
+		conn->list->v.connected(conn);
 }
 
 void connection_init_server(struct connection_list *list,
@@ -147,7 +145,6 @@
 	conn->name = i_strdup(name);
 	conn->fd_in = fd_in;
 	conn->fd_out = fd_out;
-	connection_init_io(conn);
 	connection_init_streams(conn);
 
 	DLLIST_PREPEND(&list->connections, conn);
@@ -187,7 +184,7 @@
 	if (conn->to != NULL)
 		timeout_remove(&conn->to);
 
-	connection_init_io(conn);
+	connection_init_streams(conn);
 }
 
 int connection_client_connect(struct connection *conn)
@@ -214,9 +211,8 @@
 					       connection_connect_timeout, conn);
 		}
 	} else {
-		connection_init_io(conn);
+		connection_init_streams(conn);
 	}
-	connection_init_streams(conn);
 	return 0;
 }
 
diff -r 211fbc872ed4 -r 64725ff9c297 src/lib/connection.h
--- a/src/lib/connection.h	Sun Jul 08 09:00:57 2012 +0300
+++ b/src/lib/connection.h	Sun Jul 08 09:18:46 2012 +0300
@@ -27,6 +27,7 @@
 
 struct connection_vfuncs {
 	void (*destroy)(struct connection *conn);
+	void (*connected)(struct connection *conn);
 
 	/* implement one of the input*() methods.
 	   They return 0 = ok, -1 = error, disconnect the client */


More information about the dovecot-cvs mailing list