Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running a task on a timer

I'd like to create a program that runs a function on an interval. I'm still very new to Elixir and do not know really where to start with this. My idea is that since we can use GenServer to create a program to sit and wait in a loop for messages, I could provide it a message (maybe :kick) and when it receives this message it would run the function.

However, that leaves one problem - how do I kick it without a cron job? Can I fire up a thread and run a timer that kicks it on an interval? If the main thread dies - is there an easy way to be notified and restart it?

Thank you!


2 Answers

You can use timer:send_interval/2 with a GenServer. You'll need to call the function from the init/1 callback and then handle the tick messages from the handle_info callback. Here's an example that prints 0, 1, 2, ... every second:

defmodule A do
  use GenServer

  def init(_) do
    :timer.send_interval(1000, :tick)
    {:ok, 0}
  end

  def handle_info(:tick, state) do
    IO.inspect state
    {:noreply, state + 1}
  end
end
iex(1)> GenServer.start_link(A, [])
{:ok, #PID<0.94.0>}
0
1
2
3
4
...

If the main thread dies - is there an easy way to be notified and restart it?

You should look into Supervisors. The GenServer above can be added as a "worker" to a Supervisor. The Supervisor can handle restarting the GenServer if it exits for any reason.

like image 51
Dogbert Avatar answered Apr 25 '26 02:04

Dogbert


@Dogbert mentionned using using the send_interval function from Erlang, which would be used like so : :timer.send_interval(milliseconds, process, message).

A quick Google search however, netted me the quantum-elixir library which appears to be capable of cron like scheduling, as well as scheduling tasks at runtime.

like image 40
brodeuralexis Avatar answered Apr 25 '26 02:04

brodeuralexis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!