#include <stdlib.h>
#include "poll-loop.h"
-
-#define THIS_MODULE VLM_reconnect
#include "vlog.h"
+VLOG_DEFINE_THIS_MODULE(reconnect);
+
#define STATES \
STATE(VOID, 1 << 0) \
STATE(BACKOFF, 1 << 1) \
int max_backoff;
int probe_interval;
bool passive;
+ enum vlog_level info; /* Used for informational messages. */
/* State. */
enum state state;
struct reconnect *fsm = xzalloc(sizeof *fsm);
fsm->name = xstrdup("void");
- fsm->min_backoff = 1000;
- fsm->max_backoff = 8000;
- fsm->probe_interval = 5000;
+ fsm->min_backoff = RECONNECT_DEFAULT_MIN_BACKOFF;
+ fsm->max_backoff = RECONNECT_DEFAULT_MAX_BACKOFF;
+ fsm->probe_interval = RECONNECT_DEFAULT_PROBE_INTERVAL;
fsm->passive = false;
+ fsm->info = VLL_INFO;
fsm->state = S_VOID;
fsm->state_entered = now;
}
}
+/* If 'quiet' is true, 'fsm' will log informational messages at level VLL_DBG,
+ * by default keeping them out of log files. This is appropriate if the
+ * connection is one that is expected to be short-lived, so that the log
+ * messages are merely distracting.
+ *
+ * If 'quiet' is false, 'fsm' logs informational messages at level VLL_INFO.
+ * This is the default.
+ *
+ * This setting has no effect on the log level of debugging, warning, or error
+ * messages. */
+void
+reconnect_set_quiet(struct reconnect *fsm, bool quiet)
+{
+ fsm->info = quiet ? VLL_DBG : VLL_INFO;
+}
+
/* Returns 'fsm''s name. */
const char *
reconnect_get_name(const struct reconnect *fsm)
}
/* Return the minimum number of milliseconds to back off between consecutive
- * connection attempts. The default is 1000 ms. */
+ * connection attempts. The default is RECONNECT_DEFAULT_MIN_BACKOFF. */
int
reconnect_get_min_backoff(const struct reconnect *fsm)
{
}
/* Return the maximum number of milliseconds to back off between consecutive
- * connection attempts. The default is 8000 ms. */
+ * connection attempts. The default is RECONNECT_DEFAULT_MAX_BACKOFF. */
int
reconnect_get_max_backoff(const struct reconnect *fsm)
{
* attempts.
*
* 'min_backoff' must be at least 1000, and 'max_backoff' must be greater than
- * or equal to 'min_backoff'. */
+ * or equal to 'min_backoff'.
+ *
+ * Pass 0 for 'min_backoff' or 'max_backoff' or both to use the defaults. */
void
reconnect_set_backoff(struct reconnect *fsm, int min_backoff, int max_backoff)
{
fsm->min_backoff = MAX(min_backoff, 1000);
- fsm->max_backoff = max_backoff ? MAX(max_backoff, 1000) : 8000;
+ fsm->max_backoff = (max_backoff
+ ? MAX(max_backoff, 1000)
+ : RECONNECT_DEFAULT_MAX_BACKOFF);
if (fsm->min_backoff > fsm->max_backoff) {
fsm->max_backoff = fsm->min_backoff;
}
VLOG_WARN("%s: connection dropped (%s)",
fsm->name, strerror(error));
} else if (error == EOF) {
- VLOG_INFO("%s: connection closed by peer", fsm->name);
+ VLOG(fsm->info, "%s: connection closed by peer", fsm->name);
} else {
- VLOG_INFO("%s: connection dropped", fsm->name);
+ VLOG(fsm->info, "%s: connection dropped", fsm->name);
}
} else if (fsm->state == S_LISTENING) {
if (error > 0) {
VLOG_WARN("%s: error listening for connections (%s)",
fsm->name, strerror(error));
} else {
- VLOG_INFO("%s: error listening for connections", fsm->name);
+ VLOG(fsm->info, "%s: error listening for connections",
+ fsm->name);
}
} else {
const char *type = fsm->passive ? "listen" : "connection";
VLOG_WARN("%s: %s attempt failed (%s)",
fsm->name, type, strerror(error));
} else {
- VLOG_INFO("%s: %s attempt timed out", fsm->name, type);
+ VLOG(fsm->info, "%s: %s attempt timed out", fsm->name, type);
}
}
fsm->backoff *= 2;
}
if (fsm->passive) {
- VLOG_INFO("%s: waiting %.3g seconds before trying to "
+ VLOG(fsm->info, "%s: waiting %.3g seconds before trying to "
"listen again", fsm->name, fsm->backoff / 1000.0);
} else {
- VLOG_INFO("%s: waiting %.3g seconds before reconnect",
+ VLOG(fsm->info, "%s: waiting %.3g seconds before reconnect",
fsm->name, fsm->backoff / 1000.0);
}
}
/* Tell 'fsm' that a connection or listening attempt is in progress.
*
* The FSM will start a timer, after which the connection or listening attempt
- * will be aborted (by returning RECONNECT_DISCONNECT from reconect_run()). */
+ * will be aborted (by returning RECONNECT_DISCONNECT from
+ * reconnect_run()). */
void
reconnect_connecting(struct reconnect *fsm, long long int now)
{
if (fsm->state != S_CONNECT_IN_PROGRESS) {
if (fsm->passive) {
- VLOG_INFO("%s: listening...", fsm->name);
+ VLOG(fsm->info, "%s: listening...", fsm->name);
} else {
- VLOG_INFO("%s: connecting...", fsm->name);
+ VLOG(fsm->info, "%s: connecting...", fsm->name);
}
reconnect_transition__(fsm, now, S_CONNECT_IN_PROGRESS);
}
reconnect_listening(struct reconnect *fsm, long long int now)
{
if (fsm->state != S_LISTENING) {
- VLOG_INFO("%s: listening...", fsm->name);
+ VLOG(fsm->info, "%s: listening...", fsm->name);
reconnect_transition__(fsm, now, S_LISTENING);
}
}
if (!is_connected_state(fsm->state)) {
reconnect_connecting(fsm, now);
- VLOG_INFO("%s: connected", fsm->name);
+ VLOG(fsm->info, "%s: connected", fsm->name);
reconnect_transition__(fsm, now, S_ACTIVE);
fsm->last_connected = now;
}