Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Mailbox Server

deprecated_mailbox_server.livemd

Mailbox Server

Mix.install([
  {:jason, "~> 1.4"},
  {:kino, "~> 0.9", override: true},
  {:youtube, github: "brooklinjazz/youtube"},
  {:hidden_cell, github: "brooklinjazz/hidden_cell"}
])

Navigation

Home Report An Issue Asynchronous MessagesScore Tracker

Mailbox Server

Earlier you created a Process Mailbox using purely processes. Now you’re going to create a similar mailbox using GenServer.

To test your solution, you can use :sys.get_state/1 to get the current state of your mailbox. This should only be used for debugging purposes, not for retrieving values from state in a real-world application.

{:ok, mailbox_pid} = GenServer.start_link(Mailbox, [])

GenServer.cast(mailbox_pid, {:mail, %{title: "Title 1", content: "Content 1"}})
GenServer.cast(mailbox_pid, {:mail, %{title: "Title 2", content: "Content 2"}})

:sys.get_state(mailbox_pid)
[%{title: "Title 2", content: "Content 2"}, %{title: "Title 1", content: "Content 1"}]

Example Solution

defmodule Mailbox do
  use GenServer

  def start_link(state \\ []) do
    GenServer.start_link(__MODULE__, state)
  end

  def send(mailbox_pid, mail) do
    GenServer.cast(mailbox_pid, {:mail, mail})
  end

  def all_messages(mailbox_pid) do
    GenServer.call(mailbox_pid, :all_messages)
  end

  @impl true
  def init(state) do
    {:ok, state}
  end

  @impl true
  def handle_call(:all_messages, _from, state) do
    {:noreply, state, state}
  end

  @impl true
  def handle_cast({:mail, mail}, state) do
    {:noreply, [mail | state]}
  end

  def handle_info({:mail, mail}, state) do
    {:noreply, [mail | state]}
  end
end

Implement the Mailbox GenServer as documented below.

defmodule Mailbox do
  use GenServer

  @doc """
  Start a mailbox server.

  ## Examples

      iex> {:ok, pid} = Mailbox.start_link([])
      iex> :sys.get_state(pid)
      []

      Allow the mailbox to start with a default list of messages.

      iex> {:ok, pid} = Mailbox.start_link(["Welcome to your mailbox!"])
      iex> :sys.get_state(pid)
      ["Welcome to your mailbox!"]
  """
  def start_link(_opts) do
  end

  @doc """
  Asynchronously Send a message to a mailbox server.

  ## Examples

      iex> {:ok, pid} = Mailbox.start_link([])
      iex> Mailbox.send(pid, "Message 1")
      iex> Mailbox.send(pid, "Message 2")
      iex> :sys.get_state(pid)
      ["Message 2", "Message 1"]
  """
  def send(mailbox_pid, message) do
  end

  @doc """
  Synchonously retrieve all messages in a mailbox server.

  ## Examples

      iex> {:ok, pid} = Mailbox.start_link([])
      iex> Mailbox.all_messages(pid)
      []
  """
  def all_messages(mailbox_pid) do
  end

  @doc """
  Required callback to start a GenServer.

  ## Examples

      iex> {:ok, _pid} = GenServer.start_link(Mailbox, [])
  """
  @impl true
  def init(state) do
  end

  @doc """
  Callback to synchronously retrieve a `Mailbox`'s state.

  ## Examples

      iex> {:ok, pid} = GenServer.start_link(Mailbox, ["Welcome"])
      iex> GenServer.call(pid, :all_messages)
      ["Welcome"]
  """
  @impl true
  def handle_call(:all_messages, _from, state) do
  end

  @doc """
  Callback for receiving a `cast` message and storing it in the `Mailbox`'s state.

  ## Examples

      iex> {:ok, pid} = GenServer.start_link(Mailbox, [])
      iex> GenServer.cast(pid, {:mail, "Message 1"})
      iex> GenServer.cast(pid, {:mail, "Message 2"})
      iex> :sys.get_state(pid)
      ["Message 2", "Message 1"]
  """
  @impl true
  def handle_cast({:mail, mail}, state) do
  end

  @doc """
  Callback for receiving "regular" messages and storing them in the `Mailbox`'s state.

  ## Examples

      iex> {:ok, pid} = GenServer.start_link(Mailbox, [])
      iex> Process.send(pid, {:mail, "Message 1"}, [])
      iex> Process.send(pid, {:mail, "Message 2"}, [])
      iex> :sys.get_state(pid)
      ["Message 2", "Message 1"]
  """
  @impl true
  def handle_info({:mail, mail}, state) do
  end
end

Commit Your Progress

DockYard Academy now recommends you use the latest Release rather than forking or cloning our repository.

Run git status to ensure there are no undesirable changes. Then run the following in your command line from the curriculum folder to commit your progress.

$ git add .
$ git commit -m "finish Mailbox Server exercise"
$ git push

We’re proud to offer our open-source curriculum free of charge for anyone to learn from at their own pace.

We also offer a paid course where you can learn from an instructor alongside a cohort of your peers. We will accept applications for the June-August 2023 cohort soon.

Navigation

Home Report An Issue Asynchronous MessagesScore Tracker