Adding periodic task in Elixir with OTP

In this post, I’ll show how to create a simple periodic task using Elixir OTP.

In this example, we’ll create a simple server calculator. For somehow, we want to keep adding numbers periodically over time. The initial structure for this process is:


This content originally appeared on DEV Community and was authored by rafaquelhodev

In this post, I'll show how to create a simple periodic task using Elixir OTP.

In this example, we'll create a simple server calculator. For somehow, we want to keep adding numbers periodically over time. The initial structure for this process is:

defmodule Calculator do
  use GenServer

  @doc """
  Starts the calculator.
  """
  def start_link(opts) do
    GenServer.start_link(__MODULE__, :ok, opts)
  end

  @impl true
  def init(:ok) do
    IO.puts("starting calculator")
    {:ok, 0}
  end

  @impl true
  def handle_call({:add, num}, _from, state) do
    result = state + num
    IO.puts(result)
    {:reply, {:ok, result}, result}
  end

  def add(server, num) do
    {:ok, result} = GenServer.call(server, {:add, num})
    result
  end
end

Here, we can add a number by sending a message {:add, num} to the server. The client function for this purpose is add/2.

Then, we need to create a new process that will handle the periodic tasks.

defmodule Periodic do
  use GenServer

  defstruct freq: nil, server: nil, callback: nil

  def start_link(opts) do
    GenServer.start_link(__MODULE__, :ok, opts)
  end

  @impl true
  def init(:ok) do
    {:ok, %{}}
  end

  @impl true
  def handle_call({:periodic, data}, _from, state) do
    Process.send_after(data.server, {:tick, data}, data.freq)

    {:reply, data, state}
  end

  @impl true
  def handle_info({:tick, data}, state) do
    data.callback.()

    Process.send_after(data.server, {:tick, data}, data.freq)

    {:noreply, state}
  end

  def retry(server, data) do
    data = Map.put(data, :server, server)
    GenServer.call(data.server, {:periodic, data})
  end
end

The periodic task is created using the Process.send_after/3 function. By doing this, a message {:tick, data} is sent to the server after a time of data.freq ms.

The idea behind this server is that the client must provide a callback function that is run periodically in a frequency (in ms) also defined by the client. Therefore, the client must provide two inputs: callback and freq.

In order to run a periodic task, a client must call the retry/2 function, passing the callback and freq information.

Finally, we need to define the periodic task that must be run the in Calculator server. Remember, we want to keep adding numbers periodically. For this, we define a new function add_periodic and a constant freq (set to be 1000 ms) at the Calculator module:

defmodule Calculator do
  ...
  alias Periodic

  @freq 1000

  def add_periodic(server, num, freq \\ @freq) do
    {:ok, pid} = Periodic.start_link([])

    callback = fn -> add(server, num) end

    Periodic.retry(pid, %Periodic{freq: freq, callback: callback})
  end

The entire code can be found HERE .

Usage example:

First open the iex shell by:

iex -S mix

Then,

import Calculator

{:ok, pid} = Calculator.start_link([])

Calculator.add_periodic(pid, 2)

And voila, we'll see something like this:

2
4
6
8
...


This content originally appeared on DEV Community and was authored by rafaquelhodev


Print Share Comment Cite Upload Translate Updates
APA

rafaquelhodev | Sciencx (2022-03-31T13:01:44+00:00) Adding periodic task in Elixir with OTP. Retrieved from https://www.scien.cx/2022/03/31/adding-periodic-task-in-elixir-with-otp/

MLA
" » Adding periodic task in Elixir with OTP." rafaquelhodev | Sciencx - Thursday March 31, 2022, https://www.scien.cx/2022/03/31/adding-periodic-task-in-elixir-with-otp/
HARVARD
rafaquelhodev | Sciencx Thursday March 31, 2022 » Adding periodic task in Elixir with OTP., viewed ,<https://www.scien.cx/2022/03/31/adding-periodic-task-in-elixir-with-otp/>
VANCOUVER
rafaquelhodev | Sciencx - » Adding periodic task in Elixir with OTP. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/03/31/adding-periodic-task-in-elixir-with-otp/
CHICAGO
" » Adding periodic task in Elixir with OTP." rafaquelhodev | Sciencx - Accessed . https://www.scien.cx/2022/03/31/adding-periodic-task-in-elixir-with-otp/
IEEE
" » Adding periodic task in Elixir with OTP." rafaquelhodev | Sciencx [Online]. Available: https://www.scien.cx/2022/03/31/adding-periodic-task-in-elixir-with-otp/. [Accessed: ]
rf:citation
» Adding periodic task in Elixir with OTP | rafaquelhodev | Sciencx | https://www.scien.cx/2022/03/31/adding-periodic-task-in-elixir-with-otp/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.