changeset 22648:6bd018a94a57

director: Don't block too long when sending users during director handshake All the other work is blocked while the users are being sent.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Mon, 06 Nov 2017 01:30:13 +0200
parents 641236fac254
children bb7c452e3662
files src/director/director-connection.c
diffstat 1 files changed, 9 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/director/director-connection.c	Sun Nov 05 21:36:55 2017 +0200
+++ b/src/director/director-connection.c	Mon Nov 06 01:30:13 2017 +0200
@@ -82,6 +82,9 @@
    notification and reset the last_sync_seq */
 #define DIRECTOR_SYNC_STALE_TIMESTAMP_RESET_SECS (60*2)
 #define DIRECTOR_MAX_CLOCK_DIFF_WARN_SECS 1
+/* How many USER entries to send during handshake before going back to ioloop
+   to see if there's other work to be done as well. */
+#define DIRECTOR_HANDSHAKE_MAX_USERS_SENT_PER_FLUSH 10000
 
 #if DIRECTOR_CONNECTION_DONE_TIMEOUT_MSECS <= DIRECTOR_CONNECTION_PING_TIMEOUT_MSECS
 #  error DIRECTOR_CONNECTION_DONE_TIMEOUT_MSECS is too low
@@ -1984,6 +1987,7 @@
 	struct user *user;
 	string_t *str = t_str_new(128);
 	char dec_buf[MAX_INT_STRLEN];
+	unsigned int sent_count = 0;
 	int ret;
 
 	i_assert(conn->version_received);
@@ -2000,6 +2004,11 @@
 			str_append(str, "\tw");
 		str_append_c(str, '\n');
 		director_connection_send(conn, str_c(str));
+		if (++sent_count >= DIRECTOR_HANDSHAKE_MAX_USERS_SENT_PER_FLUSH) {
+			/* Don't send too much at once to avoid hangs */
+			timeout_reset(conn->to_ping);
+			return 0;
+		}
 
 		if (o_stream_get_buffer_used_size(conn->output) >= OUTBUF_FLUSH_THRESHOLD) {
 			if ((ret = o_stream_flush(conn->output)) <= 0) {