What is handle_info in Elixir?
Overview
Before diving into the details of handle_info in Elixir, we’ll talk about its preliminaries:
GenServer
For asynchronous code execution, keeping state, and tracing and reporting errors in Elixir, we can use a generic server process, GenServer. Not only can it fit into a supervision tree, but also has many standard interface functions for a more abstract codebase.
Callbacks
While using GenServer, we only need to write handle_call/3 and init/1 are two examples of them.
These callbacks allow us to add our logic to the GenServer process. Next, we’ll see the callback, handle_info.
The handle_info callback
Messages that do not come from GenServer.call/2 or GenServer.cast/2 are handled by the handle_info/2 callback. It can also be used to handle monitor DOWN messages sent by Process.monitor/1.
Another example can be a message sent from Process.send_after/4.
Syntax
handle_info(msg, state)
Parameters
handle_info/2 takes two parameters, depending on the functionality.
-
msg: This is the message. -
state: This is the state of the GenServer. -
The message is
timeoutwhenever a timeout occurs.
handle_info(msg :: :timeout | term(), state :: term()) ::{:noreply, new_state}| {:noreply, new_state, timeout() | :hibernate | {:continue, term()}}| {:stop, reason :: term(), new_state}# when new_state: term()
Return value
-
To continue the loop with new state, it returns
{:noreply, new_state}. -
To also set a timeout, it returns
{:noreply, new_state, timeout}. -
To hibernate the process before continuing, it returns
{:noreply, new_state, :hibernate}. -
To immediately invoke
handle_continue/2with the value ofcontinueas the first argument, it returns{:noreply, new_state, {:continue, continue}}. -
To stop the loop and
terminate/2with the reasonreasonand statenew_state, it returns{:stop, reason, new_state}. It will also exit the process with reasonreason.
Code example
In the widget’s terminal below, we execute the following function:
Period.start_link({})
This would start the init/1 function, which would start the schedule_work() function. The schedule_work() would then trigger the handle_info/2 callback using the send_after/4.
We’ll be printing "work completed" every 5 seconds to the terminal.
defmodule Chat.MixProject do
use Mix.Project
def project do
[
app: :chat,
version: "0.1.0",
elixir: "~> 1.13",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
]
end
# Run "mix help deps" to learn about dependencies.
defp deps do
[
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]
end
end
Free Resources