dovecot-2.0: lib-master: Avoid sending status updates to master ...

dovecot at dovecot.org dovecot at dovecot.org
Thu Mar 4 20:19:07 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/df4d4fd0db00
changeset: 10833:df4d4fd0db00
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Mar 04 20:00:01 2010 +0200
description:
lib-master: Avoid sending status updates to master too often.

diffstat:

 src/lib-master/master-service-private.h |   4 ++++
 src/lib-master/master-service.c         |  34 +++++++++++++++++++++++++++++++---
 2 files changed, 35 insertions(+), 3 deletions(-)

diffs (81 lines):

diff -r 43a278ca5354 -r df4d4fd0db00 src/lib-master/master-service-private.h
--- a/src/lib-master/master-service-private.h	Thu Mar 04 19:59:39 2010 +0200
+++ b/src/lib-master/master-service-private.h	Thu Mar 04 20:00:01 2010 +0200
@@ -33,7 +33,11 @@
 	struct io *io_status_write, *io_status_error;
 	unsigned int service_count_left;
 	unsigned int total_available_count;
+
 	struct master_status master_status;
+	unsigned int last_sent_status_avail_count;
+	time_t last_sent_status_time;
+	struct timeout *to_status;
 
 	void (*die_callback)(void);
 	struct timeout *to_die;
diff -r 43a278ca5354 -r df4d4fd0db00 src/lib-master/master-service.c
--- a/src/lib-master/master-service.c	Thu Mar 04 19:59:39 2010 +0200
+++ b/src/lib-master/master-service.c	Thu Mar 04 20:00:01 2010 +0200
@@ -634,6 +634,8 @@
 		timeout_remove(&service->to_die);
 	if (service->to_overflow_state != NULL)
 		timeout_remove(&service->to_overflow_state);
+	if (service->to_status != NULL)
+		timeout_remove(&service->to_status);
 	if (service->io_status_error != NULL)
 		io_remove(&service->io_status_error);
 	if (service->io_status_write != NULL)
@@ -802,9 +804,32 @@
 void master_status_update(struct master_service *service)
 {
 	ssize_t ret;
+	bool important_update;
 
-	if (service->master_status.pid == 0 || service->delay_status_updates)
-		return; /* closed */
+	important_update = master_status_update_is_important(service);
+	if (service->master_status.pid == 0 || service->delay_status_updates ||
+	    service->master_status.available_count ==
+	    service->last_sent_status_avail_count) {
+		/* a) closed, b) updating to same state */
+		if (service->to_status != NULL)
+			timeout_remove(&service->to_status);
+		return;
+	}
+	if (ioloop_time == service->last_sent_status_time &&
+	    !important_update) {
+		/* don't spam master */
+		if (service->to_status != NULL)
+			timeout_reset(service->to_status);
+		else {
+			service->to_status =
+				timeout_add(1000, master_status_update,
+					    service);
+		}
+		return;
+	}
+
+	if (service->to_status != NULL)
+		timeout_remove(&service->to_status);
 
 	ret = write(MASTER_STATUS_FD, &service->master_status,
 		    sizeof(service->master_status));
@@ -814,6 +839,9 @@
 			/* delayed important update sent successfully */
 			io_remove(&service->io_status_write);
 		}
+		service->last_sent_status_time = ioloop_time;
+		service->last_sent_status_avail_count =
+			service->master_status.available_count;
 		service->initial_status_sent = TRUE;
 	} else if (ret == 0) {
 		/* shouldn't happen? */
@@ -824,7 +852,7 @@
 		if (errno != EPIPE)
 			i_error("write(master_status_fd) failed: %m");
 		service->master_status.pid = 0;
-	} else if (master_status_update_is_important(service)) {
+	} else if (important_update) {
 		/* reader is busy, but it's important to get this notification
 		   through. send it when possible. */
 		if (service->io_status_write == NULL) {


More information about the dovecot-cvs mailing list