Cancel Eio Timer

Hi,
I have this primitive timer mechanism that loops forever. This is like a notification when Eio.Condition is set.

 let rec  periodic_timer () =
   Eio_main.run @@ fun env ->
   let timeout_duration = election_timeout in
   let term_started = current_term.currentterm in
   let mutex = Eio.Mutex.create() in
   let cond = Eio.Condition.create () in
   let clock = Eio.Stdenv.clock env in
   Fiber.both (fun () ->
    let rec loop () =
        Eio.Time.sleep clock 1.0;

        Eio.Condition.broadcast cond;

      Fiber.yield ();
      loop ()
    in
    loop ()
  )

  (fun () ->
    let rec loop () =
       traceln "Waiting for timeout event ";
       await_timeout cond;
      (* checkelection_state mutex timeout_duration term_started; *)
      (* Any other logic *)

       traceln "timeout event ";
      Fiber.yield ();
      loop ()
    in
    loop ()
  );

This works for now. If I have to stop this I can probably check if a value has changed or not and then choose not to sleep and continue running the timer. This is my idea of a manual check to stop this timer loop.

But I also have this code.


  let current_term = { currentterm = 0; changed = Eio.Condition.create () }

  (* TODO Use effectively this Pattern that awaits a change. *)
  let setterm mutex value=
      Eio.Mutex.use_rw ~protect:true mutex (fun () ->
        current_term.currentterm <- !value)


  let await_term_change t =
    while t.currentterm <> 0 do Eio.Condition.await_no_mutex t.changed done;
    traceln "Current term is set"

that can start the timer again based on a condition. I am trying to figure out how to set up a link between this Eio.condition and the timer to stop the timer. I will restart it elsewhere based on some other condition.

Is there a Eio mechanism that can cancel and restart this timer ? I was also trying not to use a ‘loop’ but this works.
Thanks.

Note: Eio_main.run should only be run once in your application. Calling it in a recursive function isn’t likely to work.

I’m not quite sure what you’re trying to do, but for a repeating timer that can be paused, something like this should work:

let cond = Eio.Condition.create () in
let unpaused = ref (Promise.create_resolved ()) in
...
while true do
  Promise.await !unpaused;
  Eio.Condition.broadcast cond;
  Eio.Time.Timeout.sleep delay
done

To pause, set unpaused to a new promise and resolve it to unpause.

I have refactored to use this pause. Recursive calls to perodic_timer are removed.

Thanks.