How to create an event emitter with elixir, the otp way

I think timer:apply_interval/4 should suit your needs. It is used something like this:

defmodule Tick do
  def tick do
    IO.inspect(:tick)
  end
end

:timer.apply_interval(:timer.seconds(1), Tick, :tick, [])

The arguments in order are the interval, a module name, the function to call and the arguments to call it with. Then you can send messages to your GenServers inside that function. Check out the full documentation here: apply_interval/4

Another thing to consider is that if your tick function is only ever sending simple messages to some GenServers then it is probably extremely fast, so your implementation might be OK, once wrapped in a Task and plugged into the supervision tree (if you don't care about the potential slight drift that is).


If you prefer sending a message instead of calling a function at a given interval, you can use :timer.send_interval/3

E.g. if you want to send a message to a GenServer every second as OP mentions in their answer, you could do the following:

:timer.send_interval(:timer.seconds(1), target_pid, :tick)

Where target_pid is the PID of the GenServer you want to send a message to. Then you can handle this message in your GenServer like this:

def handle_info(:tick, state) do
  do_something()
  {:noreply, state}
end