dovecot-2.2: redis: Fixed connection handling.
dovecot at dovecot.org
dovecot at dovecot.org
Fri Aug 10 05:24:40 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/64725ff9c297
changeset: 14787: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