Asynchronous Operations with GenServer
Handling Asynchronous Operations
In the previous lesson, you used GenServer to manage state and saw both call (synchronous) and cast (asynchronous). As a quick reminder: calls wait for a reply; casts do not. Today, you will focus on asynchronous work with a small but practical example — a logger process that accepts fire-and-forget writes and lets you fetch the results later.
Start a Logger Process and Initialize State
Elixir
Explanation:
use GenServerwires up the GenServer behavior.start_link/0starts the process and registers it under the module name (__MODULE__) for easy access. In this unit, we are returning to using registered names rather than the PID-based approach from Unit 2. Registered names are ideal for "singleton" services (like a logger) where you only need one instance and want to avoid the overhead of passing PIDs around manually.init/1sets the initial state to an empty list that will store log entries.
Fire-and-Forget Writes With Cast
Elixir
Explanation:
log/1usesGenServer.cast/2, which is asynchronous. The caller does not wait.handle_cast/2timestamps the message, prints it, and prepends it to the list.- We return
{:noreply, new_state}because casts do not reply. Prepending is fast; we will reorder when reading.
Read Logs With Call and Run the Flow
Elixir
Explanation:
get_logs/0usesGenServer.call/2to synchronously fetch data.handle_call/3replies with logs in chronological order by reversing the list.- We start the server, send three async logs, briefly sleep to let casts process, then fetch and print the logs.

Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal