# Cancel Eio Timer

**URL:** <https://discuss.ocaml.org/t/cancel-eio-timer/15638>\
**Category:** Learning\
**Tags:** eio\
**Created:** [November 20, 2024, 10:55am UTC](https://discuss.ocaml.org/t/cancel-eio-timer/15638 "2024-11-20T10:55:21Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mohan\_Radhakrishnan](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mohan_radhakrishnan/32/1905_2.png) [@Mohan\_Radhakrishnan](https://discuss.ocaml.org/u/Mohan_Radhakrishnan)\
**Post date:** [November 20, 2024, 10:55am UTC](https://discuss.ocaml.org/t/cancel-eio-timer/15638/1 "2024-11-20T10:55:21Z")

</div>

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

```auto
 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.

```auto

  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.

---

<div class="post-metadata">

**Author:** ![talex5](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/talex5/32/353_2.png) [@talex5](https://discuss.ocaml.org/u/talex5)\
**Post date:** [November 20, 2024, 11:48am UTC](https://discuss.ocaml.org/t/cancel-eio-timer/15638/2 "2024-11-20T11:48:39Z")

</div>

> [@Mohan\_Radhakrishnan](#):
>
> ```auto
> let rec periodic_timer () =
> Eio_main.run @@ fun env ->
> 
> ```

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:

```auto
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.

---

<div class="post-metadata">

**Author:** ![Mohan\_Radhakrishnan](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mohan_radhakrishnan/32/1905_2.png) [@Mohan\_Radhakrishnan](https://discuss.ocaml.org/u/Mohan_Radhakrishnan)\
**Post date:** [November 21, 2024, 1:38pm UTC](https://discuss.ocaml.org/t/cancel-eio-timer/15638/3 "2024-11-21T13:38:24Z")

</div>

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

Thanks.
