Tickers in Elixir
Tickers are for when you want to do something repeatedly at regular intervals. Here’s an example of a ticker that ticks periodically until we stop it.
defmodule Tickers do
def run do
# Tickers use a similar mechanism to timers: a process that sends messages
# Here we'll use a receive block to await the messages as they arrive every 500ms.
ticker_pid = spawn_link(fn -> ticker(self()) end)
receive_loop(ticker_pid)
end
defp ticker(parent_pid) do
send(parent_pid, {:tick, DateTime.utc_now()})
Process.sleep(500)
ticker(parent_pid)
end
defp receive_loop(ticker_pid) do
receive do
{:tick, time} ->
IO.puts("Tick at #{time}")
receive_loop(ticker_pid)
after
1600 ->
Process.exit(ticker_pid, :normal)
IO.puts("Ticker stopped")
end
end
end
Tickers.run()
In this Elixir version, we use a separate process to simulate the ticker. The ticker/1
function sends a message to the parent process every 500 milliseconds. The receive_loop/1
function receives these messages and prints them.
Tickers can be stopped like timers. Once a ticker is stopped, it won’t send any more messages. We’ll stop ours after 1600ms by terminating the ticker process.
When we run this program, the ticker should tick 3 times before we stop it.
$ elixir tickers.exs
Tick at 2023-06-01 12:34:56.789Z
Tick at 2023-06-01 12:34:57.290Z
Tick at 2023-06-01 12:34:57.791Z
Ticker stopped
In Elixir, we use processes and message passing to achieve concurrent behavior, which is similar to Go’s goroutines and channels. The spawn_link/1
function creates a new process, and we use send/2
and receive
for inter-process communication.
The Process.sleep/1
function is used to introduce delays, similar to time.Sleep
in Go. To stop the ticker, we use Process.exit/2
to terminate the ticker process.
This example demonstrates how to create periodic tasks in Elixir and how to use processes for concurrent programming.