Implementing the cast and call logic

Now we'll need to write our handlers for the cast (async) and call (sync) functions. We'll start with our cast, which inserts the data into the ETS table. handle_cast/2 is a function you need to implement for your GenServer to be able to deal with message casts, which takes in two arguments: the message you're sending (whatever data you're sending), and the current state of the GenServer, which in our case is going to store the table:

  def handle_cast({:write, row}, %{table: table}=state) do
:ets.insert(table, {@key, row})
{:noreply, state}
end

In our write function, we sent the cast with a tuple of the message and the data we wanted to write. The message was :write, and the data was row. We also pattern matched against the GenServer's state to get the table out. GenServer's handle_cast calls usually end with a {:noreply, state} (remember that a GenServer maintains its state via function calls passing arguments, so this is our method for maintaining state for a GenServer).

Next, we need our lookup handle_call function. handle_call takes three arguments by default: the data being passed in, the originator process that sent the function, and the state. We don't care about the originator in our case, so we'll just mark that with an underscore for now:

  def handle_call({:lookup}, _, %{table: table}=state) do
case :ets.lookup(table, @key) do
[] -> {:reply, [], state}
data ->
results = Enum.map(data, fn {_k, v} -> v end)
{:reply, results, state}
end
end

We perform our ETS lookup against the table stored in the state. If there's no data or no matching key, we'll get back a blank list, so we pattern against that first in our case statement. Otherwise, that means we have received data back from the server.

The key that we're using to store the data is :statuses, which means we'll get a data structure back from the server that looks like the following:

[ statuses: %{...}, statuses: %{...}, statuses: %{...}, ... ]

To make this data easier for our lookup function to deal with, we just enumerate over that data as if it were a list of tuples and match out the value from each of those entries. Finally, we respond back to where our call was sent from using the {:reply, data, state} response.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset