Skip to content

Commit 11d3816

Browse files
authored
Promise to pause
1 parent b6cddbd commit 11d3816

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

_posts/2024-11-05-Raft.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,3 +357,60 @@ So the function that executes the election timer based on some conditions is thi
357357

358358
{% endhighlight %}
359359

360+
## Refactoring timer event code
361+
362+
The key requirement that lead to this is a mechanism to pause and restart the timer at various stages. Further testing
363+
may disprove this hypothesis but for now we will try to reuse the timer instead of discarding and starting a new one.
364+
365+
The OCaml eio library has just such a facility. It is cleaner than the original timer shown above.
366+
I have shown only that part of the code below.
367+
368+
{% highlight ocaml %}
369+
370+
let unpaused = ref (Promise.create_resolved ())
371+
let unpaused_resolver = ref None
372+
373+
let pause () =
374+
let p, r = Promise.create() in
375+
unpaused := p;
376+
unpaused_resolver := Some r
377+
378+
let unpause () =
379+
match !unpaused_resolver with
380+
| Some r ->
381+
Promise.resolve r ()
382+
| None -> ()
383+
384+
let periodic_timer env =
385+
Eio.Switch.run @@ fun _ ->
386+
let timeout_duration = election_timeout in
387+
let term_started = current_term.currentterm in
388+
let mutex = Eio.Mutex.create() in
389+
let cond = Eio.Condition.create () in
390+
let clock = Eio.Stdenv.clock env in
391+
Fiber.both (fun () ->
392+
while true do
393+
Promise.await !unpaused;
394+
Eio.Condition.broadcast cond;
395+
Eio.Time.sleep clock 0.5;
396+
done
397+
)
398+
399+
(fun () ->
400+
let rec loop () =
401+
traceln "Waiting for timer event ";
402+
await_timeout cond;
403+
checkelection_state mutex timeout_duration term_started;
404+
405+
traceln "timer event ";
406+
Fiber.yield ();
407+
loop ()
408+
in
409+
loop ()
410+
);
411+
412+
413+
{% endhighlight %}
414+
415+
This code facilitates a mechanism that allows use to _pause_ the timer when we don't need it and start
416+
it again.

0 commit comments

Comments
 (0)