Louis Solofrizzo: 1 raft: Add new election counter metric, and fix a possible weird case with leadership 7 files changed, 48 insertions(+), 1 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~ne02ptzero/libfloat/patches/24692/mbox | git am -3Learn more about email & git
--- CMakeLists.txt | 2 ++ election.c | 3 ++- error.c | 16 ++++++++++++++++ internal.h | 7 +++++++ libfloat.h | 11 +++++++++++ log.c | 7 +++++++ raft.c | 3 +++ 7 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 error.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b53806a..e976f8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ if (LIBFLOAT_BUILD_SHARED) log.c periodic.c snapshot.c + error.c externals/list.c ) @@ -36,6 +37,7 @@ add_library(float-static STATIC log.c periodic.c snapshot.c + error.c externals/list.c ) diff --git a/election.c b/election.c index 95dd09b..e648421 100644 --- a/election.c +++ b/election.c @@ -189,6 +189,7 @@ void libfloat_request_vote_response(libfloat_ctx_t *ctx, libfloat_rpc_response_v { DEBUG(ctx, "I have a majority of votes! Assuming leadership"); libfloat_become_leader(ctx); + ctx->stat.leader_election++; } } } @@ -221,4 +222,4 @@ void libfloat_election_resign_receive(libfloat_ctx_t *ctx) { ERROR(ctx, "Restart election"); libfloat_election_start(ctx); -} \ No newline at end of file +} diff --git a/error.c b/error.c new file mode 100644 index 0000000..0eed0fb --- /dev/null +++ b/error.c @@ -0,0 +1,16 @@ +#include "internal.h" + +static char *__error = NULL; + +const char *libfloat_get_error_str(void) +{ + const char *ret = __error; + + __error = NULL; + return ret; +} + +void libfloat_set_error_str(const char *str) +{ + __error = (char *)str; +} diff --git a/internal.h b/internal.h index 3e1dff1..ad41067 100644 --- a/internal.h +++ b/internal.h @@ -80,4 +80,11 @@ void libfloat_debug(libfloat_ctx_t *ctx, const char *fmt, ...) __attribute__((fo } while (0) void libfloat_error(libfloat_ctx_t *ctx, const char *fmt, ...) __attribute__((format (printf, 2, 3))); +/*! + * \brief Set a error to be retrieved by the caller + * + * \param[in] str String to set (Constants only) + */ +void libfloat_set_error_str(const char *str); + #endif /* LIBFLOAT_INTERNAL_H */ diff --git a/libfloat.h b/libfloat.h index 1717ef8..dcce50f 100644 --- a/libfloat.h +++ b/libfloat.h @@ -43,6 +43,10 @@ struct libfloat_ctx_s { } snapshot; } persistent; + struct { + uint64_t leader_election; /*!< Count of leader elections for this cluster */ + } stat; + struct { uint32_t election_timeout; /*!< Timeout for RAFT election (ms) */ uint32_t log_commit_timeout; /*!< Timeout for log application (s) */ @@ -474,4 +478,11 @@ void libfloat_election_resign(libfloat_ctx_t *ctx); */ void libfloat_election_resign_receive(libfloat_ctx_t *ctx); +/*! + * \brief Get a string explaining an error that has happened + * + * \note This is only useful for libfloat_add_log for now + */ +const char *libfloat_get_error_str(void); + #endif /* LIBFLOAT_H */ diff --git a/log.c b/log.c index 7676da1..ad95bc7 100644 --- a/log.c +++ b/log.c @@ -11,12 +11,14 @@ bool libfloat_add_log(libfloat_ctx_t *ctx, libfloat_commit_type_t commit_type, l if (ctx->state != RAFT_STATE_LEADER) { ERROR(ctx ,"libfloat_add_log: Refusing write, not leader"); + libfloat_set_error_str("Refusing write, not leader"); return false; } entry = ctx->calloc(1, sizeof(*entry)); if (entry == NULL) { + libfloat_set_error_str("Memory error"); return false; } @@ -24,6 +26,7 @@ bool libfloat_add_log(libfloat_ctx_t *ctx, libfloat_commit_type_t commit_type, l if (entry->data == NULL) { ctx->free(entry); + libfloat_set_error_str("Memory error"); return false; } @@ -74,6 +77,7 @@ bool libfloat_add_log(libfloat_ctx_t *ctx, libfloat_commit_type_t commit_type, l ctx->free(entry->data); ctx->free(entry); ERROR(ctx, "libfloat_add_log: Refusing write, callback returned false"); + libfloat_set_error_str("User defined callback returned false"); return false; } @@ -445,6 +449,9 @@ response: if (node == NULL) node = libfloat_get_node(ctx, req->leader_id); + if (ctx->leader != node) + ctx->stat.leader_election++; + ctx->leader = node; ctx->stepping_down = false; diff --git a/raft.c b/raft.c index 1515c5b..9070b2f 100644 --- a/raft.c +++ b/raft.c @@ -44,6 +44,9 @@ void libfloat_step_down(libfloat_ctx_t *ctx) { DEBUG(ctx, "Force stepping down"); ctx->stepping_down = true; + if (ctx->state == RAFT_STATE_LEADER) + ctx->leader = NULL; + ctx->state = RAFT_STATE_NONE; } -- 2.32.0