On 1/10/24 20:29, Frode Nordahl wrote:
> The OVSDB server is mostly synchronous and single threaded.  The
> OVSDB RAFT storage engine operate under strict deadlines with
> operational impact should the deadline be overrun.
> 
> Register for cooperative multitasking so that long running
> processing elsewhere in the program may yield to allow stable
> maintenance of the cluster.
> 
> Signed-off-by: Frode Nordahl <[email protected]>
> ---
>  ovsdb/raft.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/ovsdb/raft.c b/ovsdb/raft.c
> index 8effd9ad1..6d2d9afda 100644
> --- a/ovsdb/raft.c
> +++ b/ovsdb/raft.c
> @@ -22,6 +22,7 @@
>  #include <errno.h>
>  #include <unistd.h>
>  
> +#include "cooperative-multitasking.h"
>  #include "hash.h"
>  #include "jsonrpc.h"
>  #include "lockfile.h"
> @@ -423,6 +424,8 @@ raft_make_address_passive(const char *address_)
>      }
>  }
>  
> +#define RAFT_TIMER_THRESHOLD(t) t / 3
> +
>  static struct raft *
>  raft_alloc(void)
>  {
> @@ -446,6 +449,10 @@ raft_alloc(void)
>      raft->conn_backlog_max_n_msgs = DEFAULT_MAX_BACKLOG_N_MSGS;
>      raft->conn_backlog_max_n_bytes = DEFAULT_MAX_BACKLOG_N_BYTES;
>  
> +    COOPERATIVE_MULTITASKING_REGISTER(
> +        &raft_run, raft, RAFT_TIMER_THRESHOLD(raft->election_timer),
> +        "consider increasing the election timer.");

We will not need to register here if we combine it with update.

> +
>      return raft;
>  }
>  
> @@ -991,12 +998,22 @@ raft_reset_election_timer(struct raft *raft)
>          duration += raft->election_timer;
>      }
>      raft->election_timeout = raft->election_base + duration;
> +
> +    COOPERATIVE_MULTITASKING_UPDATE(
> +        &raft_run, raft,
> +        raft->election_base,
> +        RAFT_TIMER_THRESHOLD(raft->election_base + duration));
>  }
>  
>  static void
>  raft_reset_ping_timer(struct raft *raft)
>  {
> -    raft->ping_timeout = time_msec() + raft->election_timer / 3;
> +    long long int now = time_msec();
> +
> +    raft->ping_timeout = now + RAFT_TIMER_THRESHOLD(raft->election_timer);
> +
> +    COOPERATIVE_MULTITASKING_UPDATE(
> +        &raft_run, raft, now, RAFT_TIMER_THRESHOLD(raft->election_timer));
>  }
>  
>  static void

I'm not sure we need to update whenever the timer is firing or reset.
We need to update when the raft_run() is called (to update the last_run).
And we need to update when election_timer changes the value, but this
is not necessary, since raft_run() is the only thing that changes the
election timer, so we will always have an updated value at the end of
a function.

Updating when the timers are reset is not very intuitive, also these
timers will constantly modify the value on every RAFT communication round,
which is a little hard to track.
We just need to ensure that raft_run() is called a few times within
the span of election_timer, we do not care much about exact timestamps.

Does that make sense?

Best regards, Ilya Maximets.
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to