If that is the case, then the skeleton code below should be a worker rather than a supervisor?
defmodule Notifier do
def init(state) do
Notifier.schedule_send_push_notifications
{:ok, state}
end
def handle_info(:send_push_notifications, state) do
{:ok, pid} = Task.start_link(fn -> Notifier.send_push_notifications(self(), state[:last_notified_at]) end)
%{state | notifier_task_pid: pid}
end
def schedule_send_push_notifications() do
Process.send_after(self(), :send_push_notifications, 30*1000)
end
def send_push_notifications(from, last_notified_at) do
# send push notifications
# reply with correct last_notified_at
end
end
The Notifier process is responsible for starting a task when it’s time to send the push notifications, but beyond that, this process holds some state and passively waits for messages. It feels like my understanding of workers vs supervisors is flawed.
You can create supervised children in a Supervisor with worker/3 and supervisor/3.
While worker/3 is used to start generic processes, supervisor/3 is specifically for processes that are also Supervisors. Like this you can have Supervisors that are supervised by other Supervisors, eventually creating the Supervision tree.
The module you’ve posted here is not a Supervisor, so it should be started with worker/3.
Yes, apart from supervising, supervisors should do as little as possible. While your Notifier module is pretty simple and could technically be implemented as a supervisor, the general mindset in the Erlang and Elixir community is to implement it as a worker.
I think the most important reasons are that a supervisor should not crash from buggy application code and that it should do as little work as possible in order to be able to react quickly to crashing workers.
Edit: forgot to mention that supervisors are implemented as gen_servers, so supervisors are internally no different than any other process in OTP
In your notifier module, some methods call the Task.start_link. That essentially starts a new process linked to the main one. Starting this module as a supervisor is essentially to say that if these separately created processes crash, then restart them.