Skip to content

Commit

Permalink
lib-stats: Handle better write() to stats process failing with EAGAIN
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sirainen committed Apr 18, 2016
1 parent 6da64a8 commit 14e2d75
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/lib-stats/stats-connection.c
@@ -1,20 +1,24 @@
/* 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"

#include <unistd.h>
#include <fcntl.h>

#define STATS_EAGAIN_WARN_INTERVAL_SECS 30

struct stats_connection {
int refcount;

int fd;
char *path;

bool open_failed;
time_t next_warning_timestamp;
};

static bool stats_connection_open(struct stats_connection *conn)
Expand Down Expand Up @@ -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. */
Expand Down

0 comments on commit 14e2d75

Please sign in to comment.