GenServer

How to create a scheduled job (kudos href)

Code

defmodule Jobs do
  # Jobs module is based on GenServer
  use GenServer

  # Init with `init` as initial value, then continue
  def init(init) do
    # call to handle_continue
    {:ok, init, {:continue, :work}}
  end

  # Exec the job for the first time, at the end of init
  def handle_continue(:work, state) do
    {:noreply, work_then_reschedule(state)}
  end

  # Exec the job when :work message is received
  def handle_info(:work, state) do
    {:noreply, work_then_reschedule(state)}
  end

  # Get timer from config.exs
  def get_timer_config() do
    {:ok, timer} = Application.fetch_env(:app, :timer)
    timer
  end

  # Do the important stuff
  defp work_then_reschedule(state) do
    # Modify state
    state = state + 1

    IO.puts(state)
    IO.puts("Work, then reschedule !")

    # Reschedule, later
    Process.send_after(self(), :work, get_timer_config() * 1000)

    # Return updated state
    state

  end
end

Usage

iex> {:ok, pid} = GenServer.start_link(Jobs, 1)
{:ok, #PID<0.251.0>}