Skip to content

Commit

Permalink
Add reconnect throttling to Influx output
Browse files Browse the repository at this point in the history
  • Loading branch information
zuckschwerdt committed Jan 4, 2025
1 parent bb8c653 commit 0a5c6a8
Showing 1 changed file with 29 additions and 5 deletions.
34 changes: 29 additions & 5 deletions src/output_influx.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ typedef struct {
struct data_output output;
struct mg_mgr *mgr;
struct mg_connection *conn;
struct mg_connection *timer;
int reconnect_delay;
int prev_status;
int prev_resp_code;
char hostname[64];
Expand All @@ -53,16 +55,22 @@ static void influx_client_event(struct mg_connection *nc, int ev, void *ev_data)
switch (ev) {
case MG_EV_CONNECT: {
int connect_status = *(int *)ev_data;
if (connect_status != 0) {
if (connect_status == 0) {
// Success
if (ctx) {
ctx->reconnect_delay = 0;
}
} else {
// Error, print only once
if (ctx) {
if (ctx->prev_status != connect_status)
print_logf(LOG_WARNING, "InfluxDB", "InfluxDB connect error: %s", strerror(connect_status));
ctx->conn = NULL;
}
}
if (ctx)
if (ctx) {
ctx->prev_status = connect_status;
}
break;
}
case MG_EV_HTTP_CHUNK: // response is normally empty (so mongoose thinks we received a chunk only)
Expand All @@ -80,12 +88,23 @@ static void influx_client_event(struct mg_connection *nc, int ev, void *ev_data)
}
break;
case MG_EV_CLOSE:
if (ctx) {
ctx->conn = NULL;
influx_client_send(ctx);
if (!ctx) {
break; // shutting down
}
ctx->conn = NULL;
// Timer for next connect attempt, sends us MG_EV_TIMER event
mg_set_timer(ctx->timer, mg_time() + ctx->reconnect_delay);
if (ctx->reconnect_delay < 60) {
// 0, 1, 3, 6, 10, 16, 25, 39, 60
ctx->reconnect_delay = (ctx->reconnect_delay + 1) * 3 / 2;
}
break;
case MG_EV_TIMER: {
// Try to reconnect, ends if no data to send
influx_client_send(ctx);
break;
}
}
}

static influx_client_t *influx_client_init(influx_client_t *ctx, char const *url, char const *token)
Expand Down Expand Up @@ -514,6 +533,11 @@ struct data_output *data_output_influx_create(struct mg_mgr *mgr, char *opts)
print_logf(LOG_CRITICAL, "InfluxDB", "Publishing data to InfluxDB (%s)", url);

influx->mgr = mgr;

// add dummy socket to receive timer events
struct mg_add_sock_opts timer_opts = {.user_data = influx};
influx->timer = mg_add_sock_opt(mgr, INVALID_SOCKET, influx_client_event, timer_opts);

influx_client_init(influx, url, token);

return (struct data_output *)influx;
Expand Down

0 comments on commit 0a5c6a8

Please sign in to comment.