[Tarantool-patches] [PATCH 1/2] replication: introduce ballot.can_be_leader

Serge Petrenko sergepetrenko at tarantool.org
Fri Jul 16 13:59:57 MSK 2021



16.07.2021 02:49, Vladislav Shpilevoy пишет:
> The flag tells whether the sender has election mode 'candidate' or
> 'manual'.
>
> The new field during bootstrap will help to avoid selecting a
> 'voter' as a master. Voters can't write, they are unable to boot
> themselves nor register others.
>
> @TarantoolBot document
> Title: New field - IPROTO_BALLOT_CAN_BE_LEADER
> It is sent as a part of `IPROTO_BALLOT (0x29)`. The field is a
> boolean flag which is true if the sender has `election_mode` in
> its config `'manual'` or `'candidate'`.
>
> During bootstrap the nodes able to become a leader are preferred
> over the nodes configured as `'voter'`.
>
> The field key is `0x07`.
> ---
>   src/box/box.cc             |  3 +++
>   src/box/iproto_constants.h |  1 +
>   src/box/xrow.c             | 14 ++++++++++++--
>   src/box/xrow.h             |  2 ++
>   4 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/src/box/box.cc b/src/box/box.cc
> index eeb57b04e..ef3efe3e0 100644
> --- a/src/box/box.cc
> +++ b/src/box/box.cc

Hi and thanks for the patch!

It's all good except the field name. It's rather long IMO, and may be
confused with bootsrap leader, which we try to find using ballots.

Wouldn't "can be candidate", or "is_election_candidate" be better?

I do not insist, though.
> @@ -2881,6 +2881,9 @@ void
>   box_process_vote(struct ballot *ballot)
>   {
>   	ballot->is_ro_cfg = cfg_geti("read_only") != 0;
> +	enum election_mode mode = box_check_election_mode();
> +	ballot->can_be_leader = mode == ELECTION_MODE_CANDIDATE ||
> +				mode == ELECTION_MODE_MANUAL;
>   	ballot->is_anon = replication_anon;
>   	ballot->is_ro = is_ro_summary;
>   	ballot->is_booted = is_box_configured;
> diff --git a/src/box/iproto_constants.h b/src/box/iproto_constants.h
> index 137bee9da..f0f967008 100644
> --- a/src/box/iproto_constants.h
> +++ b/src/box/iproto_constants.h
> @@ -168,6 +168,7 @@ enum iproto_ballot_key {
>   	IPROTO_BALLOT_IS_RO = 0x04,
>   	IPROTO_BALLOT_IS_ANON = 0x05,
>   	IPROTO_BALLOT_IS_BOOTED = 0x06,
> +	IPROTO_BALLOT_CAN_BE_LEADER = 0x07,
>   };
>   
>   #define bit(c) (1ULL<<IPROTO_##c)
> diff --git a/src/box/xrow.c b/src/box/xrow.c
> index 16cb2484c..a6b19ce89 100644
> --- a/src/box/xrow.c
> +++ b/src/box/xrow.c
> @@ -459,7 +459,9 @@ iproto_reply_vote(struct obuf *out, const struct ballot *ballot,
>   		mp_sizeof_uint(UINT32_MAX) +
>   		mp_sizeof_vclock_ignore0(&ballot->vclock) +
>   		mp_sizeof_uint(UINT32_MAX) +
> -		mp_sizeof_vclock_ignore0(&ballot->gc_vclock);
> +		mp_sizeof_vclock_ignore0(&ballot->gc_vclock) +
> +		mp_sizeof_uint(IPROTO_BALLOT_CAN_BE_LEADER) +
> +		mp_sizeof_bool(ballot->can_be_leader);
>   
>   	char *buf = obuf_reserve(out, max_size);
>   	if (buf == NULL) {
> @@ -471,7 +473,7 @@ iproto_reply_vote(struct obuf *out, const struct ballot *ballot,
>   	char *data = buf + IPROTO_HEADER_LEN;
>   	data = mp_encode_map(data, 1);
>   	data = mp_encode_uint(data, IPROTO_BALLOT);
> -	data = mp_encode_map(data, 6);
> +	data = mp_encode_map(data, 7);
>   	data = mp_encode_uint(data, IPROTO_BALLOT_IS_RO_CFG);
>   	data = mp_encode_bool(data, ballot->is_ro_cfg);
>   	data = mp_encode_uint(data, IPROTO_BALLOT_IS_RO);
> @@ -484,6 +486,8 @@ iproto_reply_vote(struct obuf *out, const struct ballot *ballot,
>   	data = mp_encode_vclock_ignore0(data, &ballot->vclock);
>   	data = mp_encode_uint(data, IPROTO_BALLOT_GC_VCLOCK);
>   	data = mp_encode_vclock_ignore0(data, &ballot->gc_vclock);
> +	data = mp_encode_uint(data, IPROTO_BALLOT_CAN_BE_LEADER);
> +	data = mp_encode_bool(data, ballot->can_be_leader);
>   	size_t size = data - buf;
>   	assert(size <= max_size);
>   
> @@ -1362,6 +1366,7 @@ int
>   xrow_decode_ballot(struct xrow_header *row, struct ballot *ballot)
>   {
>   	ballot->is_ro_cfg = false;
> +	ballot->can_be_leader = false;
>   	ballot->is_ro = false;
>   	ballot->is_anon = false;
>   	ballot->is_booted = true;
> @@ -1434,6 +1439,11 @@ xrow_decode_ballot(struct xrow_header *row, struct ballot *ballot)
>   				goto err;
>   			ballot->is_booted = mp_decode_bool(&data);
>   			break;
> +		case IPROTO_BALLOT_CAN_BE_LEADER:
> +			if (mp_typeof(*data) != MP_BOOL)
> +				goto err;
> +			ballot->can_be_leader = mp_decode_bool(&data);
> +			break;
>   		default:
>   			mp_next(&data);
>   		}
> diff --git a/src/box/xrow.h b/src/box/xrow.h
> index 9f61bfd47..f77fa5a9b 100644
> --- a/src/box/xrow.h
> +++ b/src/box/xrow.h
> @@ -368,6 +368,8 @@ xrow_encode_auth(struct xrow_header *row, const char *salt, size_t salt_len,
>   struct ballot {
>   	/** Set if the instance is configured in read-only mode. */
>   	bool is_ro_cfg;
> +	/** Set if the instance is an election candidate. */
> +	bool can_be_leader;
>   	/**
>   	 * A flag whether the instance is anonymous, not having an
>   	 * ID, and not going to request it.

-- 
Serge Petrenko



More information about the Tarantool-patches mailing list