static void raft_become_leader(struct raft *);
static void raft_become_follower(struct raft *);
-static void raft_reset_timer(struct raft *);
+static void raft_reset_election_timer(struct raft *);
+static void raft_reset_ping_timer(struct raft *);
static void raft_send_heartbeats(struct raft *);
static void raft_start_election(struct raft *, bool leadership_transfer);
static bool raft_truncate(struct raft *, uint64_t new_end);
hmap_init(&raft->add_servers);
hmap_init(&raft->commands);
- raft->ping_timeout = time_msec() + PING_TIME_MSEC;
- raft_reset_timer(raft);
+ raft_reset_ping_timer(raft);
+ raft_reset_election_timer(raft);
return raft;
}
}
static void
-raft_reset_timer(struct raft *raft)
+raft_reset_election_timer(struct raft *raft)
{
unsigned int duration = (ELECTION_BASE_MSEC
+ random_range(ELECTION_RANGE_MSEC));
raft->election_timeout = raft->election_base + duration;
}
+static void
+raft_reset_ping_timer(struct raft *raft)
+{
+ raft->ping_timeout = time_msec() + PING_TIME_MSEC;
+}
+
static void
raft_add_conn(struct raft *raft, struct jsonrpc_session *js,
const struct uuid *sid, bool incoming)
VLOG_INFO("term %"PRIu64": starting election", raft->term);
}
}
- raft_reset_timer(raft);
+ raft_reset_election_timer(raft);
struct raft_server *peer;
HMAP_FOR_EACH (peer, hmap_node, &raft->servers) {
raft_command_complete(raft, cmd, RAFT_CMD_TIMEOUT);
}
}
+ raft_reset_ping_timer(raft);
}
- raft->ping_timeout = time_msec() + PING_TIME_MSEC;
}
/* Do this only at the end; if we did it as soon as we set raft->left or
s->next_index++;
}
}
+ raft_reset_ping_timer(raft);
return cmd;
}
}
raft->role = RAFT_FOLLOWER;
- raft_reset_timer(raft);
+ raft_reset_election_timer(raft);
/* Notify clients about lost leadership.
*
RAFT_CMD_INCOMPLETE, 0);
}
}
+
+ raft_reset_ping_timer(raft);
}
/* Initializes the fields in 's' that represent the leader's view of the
raft->role = RAFT_LEADER;
raft->leader_sid = raft->sid;
raft->election_timeout = LLONG_MAX;
- raft->ping_timeout = time_msec() + PING_TIME_MSEC;
+ raft_reset_ping_timer(raft);
struct raft_server *s;
HMAP_FOR_EACH (s, hmap_node, &raft->servers) {
return data;
}
-static void
+/* Updates commit index in raft log. If commit index is already up-to-date
+ * it does nothing and return false, otherwise, returns true. */
+static bool
raft_update_commit_index(struct raft *raft, uint64_t new_commit_index)
{
if (new_commit_index <= raft->commit_index) {
- return;
+ return false;
}
if (raft->role == RAFT_LEADER) {
.commit_index = raft->commit_index,
};
ignore(ovsdb_log_write_and_free(raft->log, raft_record_to_json(&r)));
+ return true;
}
/* This doesn't use rq->entries (but it does use rq->n_entries). */
"usurped leadership");
return;
}
- raft_reset_timer(raft);
+ raft_reset_election_timer(raft);
/* First check for the common case, where the AppendEntries request is
* entirely for indexes covered by 'log_start' ... 'log_end - 1', something
}
}
}
- raft_update_commit_index(raft, new_commit_index);
+ if (raft_update_commit_index(raft, new_commit_index)) {
+ raft_send_heartbeats(raft);
+ }
}
static void
return false;
}
- raft_reset_timer(raft);
+ raft_reset_election_timer(raft);
return true;
}
raft_handle_install_snapshot_request__(
struct raft *raft, const struct raft_install_snapshot_request *rq)
{
- raft_reset_timer(raft);
+ raft_reset_election_timer(raft);
/*
* Our behavior here depend on new_log_start in the snapshot compared to