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;
{
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);
}
}
+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,
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 *
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);
}
} 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);
+ }
+
+ 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);
+ str_truncate(dict->conn.last_reply, 0);
+ io_loop_run(dict->ioloop);
+ }
timeout_remove(&to);
}
{
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);
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);
"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,
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);
if (conn->to != NULL)
timeout_remove(&conn->to);
- connection_init_io(conn);
+ connection_init_streams(conn);
}
int connection_client_connect(struct connection *conn)
connection_connect_timeout, conn);
}
} else {
- connection_init_io(conn);
+ connection_init_streams(conn);
}
- connection_init_streams(conn);
return 0;
}