From 14e2d75759a311ee6baf3b0416380fc7b3ed2448 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 15 Apr 2016 15:01:20 +0300 Subject: [PATCH] lib-stats: Handle better write() to stats process failing with EAGAIN It only means that the stats process is too busy and the FIFO is filled up. Retrying the write later should work. We also don't want to log too much about the same warning, so do it only once per 30 seconds. --- src/lib-stats/stats-connection.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/lib-stats/stats-connection.c b/src/lib-stats/stats-connection.c index 389ed861c4..740acad7df 100644 --- a/src/lib-stats/stats-connection.c +++ b/src/lib-stats/stats-connection.c @@ -1,6 +1,7 @@ /* Copyright (c) 2011-2016 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "ioloop.h" #include "str.h" #include "master-service.h" #include "stats-connection.h" @@ -8,6 +9,8 @@ #include #include +#define STATS_EAGAIN_WARN_INTERVAL_SECS 30 + struct stats_connection { int refcount; @@ -15,6 +18,7 @@ struct stats_connection { char *path; bool open_failed; + time_t next_warning_timestamp; }; static bool stats_connection_open(struct stats_connection *conn) @@ -89,7 +93,17 @@ void stats_connection_send(struct stats_connection *conn, const string_t *str) } ret = write(conn->fd, str_data(str), str_len(str)); - if (ret != (ssize_t)str_len(str)) { + if (ret == (ssize_t)str_len(str)) { + /* success */ + } else if (ret < 0 && errno == EAGAIN) { + /* stats process is busy */ + if (ioloop_time > conn->next_warning_timestamp) { + i_warning("write(%s) failed: %m (stats process is busy)", conn->path); + conn->next_warning_timestamp = ioloop_time + + STATS_EAGAIN_WARN_INTERVAL_SECS; + } + } else { + /* error - reconnect */ if (ret < 0) { /* don't log EPIPE errors. they can happen when Dovecot is stopped. */ -- 2.47.3