How to stop :timer

I have this code, i want to stop_clock right now with erlang :timer. How can I do this ? Is it possible ?

 def handle_event("start_clock", %{"id" => id}, socket) do
    :timer.send_interval(1000, self(), :tick)

    card = Kanban.get_card_from_modal!(id)

    estimated_duration = card.task.estimated_duration

    time = estimated_duration / 60
    hour = trunc(time)
    e = time - hour
    minute = round(e * 60)
    second = socket.assigns.second

    {:noreply, socket |> assign(data_card_id: card.id, time: estimated_duration ,hour: hour, minute: minute, second: second)}
  end

  def handle_event("stop_clock", %{"id" => id}, socket) do
    :timer.cancel(:tick)
   {:noreply, socket}
  end

Timers are not identified my the message they send, but the reference returned when starting the timer.

ref = :timer.send_interval(1000, self(), :tick)
:timer.cancel(ref)

In your case you’d need to retain the reference in your state, e.g. in socket.private.

2 Likes

I think that its works but I have tried :timer.kill_after(0) and it works too

Thanks you

iex(1)> :timer.kill_after(0)
** (EXIT from #PID<0.109.0>) shell process exited with reason: killed

I think that’s because it kills the current process, not because it’s actually killing your timer properly.

5 Likes

Creating timers using the functions :erlang.send_after/3 and :erlang.start_timer/3 is much more efficient than using the timers provided by the :timer module.

5 Likes