dovecot-2.1: director: Changes to PING handling.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Apr 3 00:09:09 EEST 2012
details: http://hg.dovecot.org/dovecot-2.1/rev/168e3b5cb6e8
changeset: 14369:168e3b5cb6e8
user: Timo Sirainen <tss at iki.fi>
date: Mon Apr 02 23:28:22 2012 +0300
description:
director: Changes to PING handling.
Use larger ping timeouts. While waiting for sync keep doing rapid pings
until the sync is finished, not just once.
diffstat:
src/director/director-connection.c | 63 +++++++++++++++++++++----------------
src/director/director-connection.h | 3 +-
src/director/director.c | 11 +++++-
3 files changed, 46 insertions(+), 31 deletions(-)
diffs (203 lines):
diff -r 7f4c35fcae80 -r 168e3b5cb6e8 src/director/director-connection.c
--- a/src/director/director-connection.c Mon Apr 02 21:49:05 2012 +0300
+++ b/src/director/director-connection.c Mon Apr 02 23:28:22 2012 +0300
@@ -23,13 +23,13 @@
#define MAX_OUTBUF_SIZE (1024*1024*10)
#define OUTBUF_FLUSH_THRESHOLD (1024*128)
/* Max idling time while connecting/handshaking before disconnecting */
-#define DIRECTOR_CONNECTION_INIT_TIMEOUT_MSECS (2*1000)
+#define DIRECTOR_CONNECTION_INIT_TIMEOUT_MSECS (10*1000)
/* How long to wait for PONG after PING request */
-#define DIRECTOR_CONNECTION_PING_TIMEOUT_MSECS (2*1000)
+#define DIRECTOR_CONNECTION_PING_TIMEOUT_MSECS (10*1000)
/* How long to wait to send PING when connection is idle */
#define DIRECTOR_CONNECTION_PING_INTERVAL_MSECS (15*1000)
/* How long to wait before sending PING while waiting for SYNC reply */
-#define DIRECTOR_CONNECTION_SYNC_TIMEOUT_MSECS 1000
+#define DIRECTOR_CONNECTION_PING_SYNC_INTERVAL_MSECS 1000
/* If outgoing director connection exists for less than this many seconds,
mark the host as failed so we won't try to reconnect to it immediately */
#define DIRECTOR_SUCCESS_MIN_CONNECT_SECS 10
@@ -61,7 +61,7 @@
unsigned int ignore_host_events:1;
unsigned int handshake_sending_hosts:1;
unsigned int ping_waiting:1;
- unsigned int sync_ping:1;
+ unsigned int synced:1;
};
static void director_connection_ping(struct director_connection *conn);
@@ -636,6 +636,19 @@
return TRUE;
}
+static void
+director_connection_set_ping_timeout(struct director_connection *conn)
+{
+ unsigned int msecs;
+
+ msecs = conn->synced || !conn->handshake_received ?
+ DIRECTOR_CONNECTION_PING_INTERVAL_MSECS :
+ DIRECTOR_CONNECTION_PING_SYNC_INTERVAL_MSECS;
+
+ timeout_remove(&conn->to_ping);
+ conn->to_ping = timeout_add(msecs, director_connection_ping, conn);
+}
+
static void director_handshake_cmd_done(struct director_connection *conn)
{
struct director *dir = conn->dir;
@@ -668,10 +681,7 @@
director_sync_send(dir, dir->self_host, dir->sync_seq,
DIRECTOR_VERSION_MINOR);
}
- if (conn->to_ping != NULL)
- timeout_remove(&conn->to_ping);
- conn->to_ping = timeout_add(DIRECTOR_CONNECTION_PING_INTERVAL_MSECS,
- director_connection_ping, conn);
+ director_connection_set_ping_timeout(conn);
}
static bool
@@ -893,11 +903,9 @@
{
if (!conn->ping_waiting)
return TRUE;
+ conn->ping_waiting = FALSE;
- conn->ping_waiting = FALSE;
- timeout_remove(&conn->to_ping);
- conn->to_ping = timeout_add(DIRECTOR_CONNECTION_PING_INTERVAL_MSECS,
- director_connection_ping, conn);
+ director_connection_set_ping_timeout(conn);
return TRUE;
}
@@ -971,8 +979,6 @@
char *line;
bool ret;
- if (conn->to_ping != NULL)
- timeout_reset(conn->to_ping);
switch (i_stream_read(conn->input)) {
case 0:
return;
@@ -1007,6 +1013,8 @@
}
}
director_sync_thaw(dir);
+ if (conn != NULL)
+ timeout_reset(conn->to_ping);
}
static void director_connection_send_directors(struct director_connection *conn,
@@ -1056,6 +1064,7 @@
if (o_stream_get_buffer_used_size(conn->output) >= OUTBUF_FLUSH_THRESHOLD) {
if ((ret = o_stream_flush(conn->output)) <= 0) {
/* continue later */
+ timeout_reset(conn->to_ping);
return ret;
}
}
@@ -1068,6 +1077,7 @@
ret = o_stream_flush(conn->output);
o_stream_uncork(conn->output);
+ timeout_reset(conn->to_ping);
return ret;
}
@@ -1224,8 +1234,7 @@
user_directory_iter_deinit(&conn->user_iter);
if (conn->to != NULL)
timeout_remove(&conn->to);
- if (conn->to_ping != NULL)
- timeout_remove(&conn->to_ping);
+ timeout_remove(&conn->to_ping);
if (conn->io != NULL)
io_remove(&conn->io);
i_stream_unref(&conn->input);
@@ -1298,12 +1307,10 @@
static void director_connection_ping(struct director_connection *conn)
{
- conn->sync_ping = FALSE;
if (conn->ping_waiting)
return;
- if (conn->to_ping != NULL)
- timeout_remove(&conn->to_ping);
+ timeout_remove(&conn->to_ping);
conn->to_ping = timeout_add(DIRECTOR_CONNECTION_PING_TIMEOUT_MSECS,
director_connection_ping_timeout, conn);
director_connection_send(conn, "PING\n");
@@ -1344,18 +1351,18 @@
o_stream_uncork(conn->output);
}
-void director_connection_wait_sync(struct director_connection *conn)
+void director_connection_set_synced(struct director_connection *conn,
+ bool synced)
{
- /* switch to faster ping timeout. avoid reseting the timeout if it's
- already fast. */
- if (conn->ping_waiting || conn->sync_ping)
+ if (conn->synced == synced)
+ return;
+ conn->synced = synced;
+
+ /* switch ping timeout, unless we're already waiting for PONG */
+ if (conn->ping_waiting)
return;
- if (conn->to_ping != NULL)
- timeout_remove(&conn->to_ping);
- conn->to_ping = timeout_add(DIRECTOR_CONNECTION_SYNC_TIMEOUT_MSECS,
- director_connection_ping, conn);
- conn->sync_ping = TRUE;
+ director_connection_set_ping_timeout(conn);
}
void director_connections_deinit(struct director *dir)
diff -r 7f4c35fcae80 -r 168e3b5cb6e8 src/director/director-connection.h
--- a/src/director/director-connection.h Mon Apr 02 21:49:05 2012 +0300
+++ b/src/director/director-connection.h Mon Apr 02 23:28:22 2012 +0300
@@ -14,7 +14,8 @@
void director_connection_send(struct director_connection *conn,
const char *data);
-void director_connection_wait_sync(struct director_connection *conn);
+void director_connection_set_synced(struct director_connection *conn,
+ bool synced);
void director_connection_send_except(struct director_connection *conn,
struct director_host *skip_host,
const char *data);
diff -r 7f4c35fcae80 -r 168e3b5cb6e8 src/director/director.c
--- a/src/director/director.c Mon Apr 02 21:49:05 2012 +0300
+++ b/src/director/director.c Mon Apr 02 23:28:22 2012 +0300
@@ -230,6 +230,10 @@
timeout_remove(&dir->to_reconnect);
}
+ if (dir->left != NULL)
+ director_connection_set_synced(dir->left, TRUE);
+ if (dir->right != NULL)
+ director_connection_set_synced(dir->right, TRUE);
if (dir->to_sync != NULL)
timeout_remove(&dir->to_sync);
dir->ring_synced = TRUE;
@@ -310,9 +314,12 @@
director_connection_get_name(dir->right));
}
+ /* send PINGs to our connections more rapidly until we've synced again.
+ if the connection has actually died, we don't need to wait (and
+ delay requests) for as long to detect it */
if (dir->left != NULL)
- director_connection_wait_sync(dir->left);
- director_connection_wait_sync(dir->right);
+ director_connection_set_synced(dir->left, FALSE);
+ director_connection_set_synced(dir->right, FALSE);
director_sync_send(dir, dir->self_host, dir->sync_seq,
DIRECTOR_VERSION_MINOR);
}
More information about the dovecot-cvs
mailing list