GenServer Beispiel

Edwin Bühler
Jul 20, 2017 · 2 min read

Ein paar Zeilen Code und fertig ist ein “GenServer” Beispiel.

GenServer

Das Modul GenServer liefert die Funktionen eines generischen Servers.

Zuerst ein Module erzeugen

defmodule ShoppingList do
use GenServer
end

Den Serverprozess starten

Die erste Funktion, die implementiert wird, ist für den Start des Servers.

Die Funktion start_link() wird im GenServer-Modul drei Argumenten aufrufen.

Das erste Argument ist das Modul in dem Server-Callbacks implementiert sind.

Das nächste Argument ist ein Initialisierungsargument für das Modul. Da in diesem Beispiel kein Argument erforderlich ist, wird das :ok Atom übergeben.

Und schließlich ist das dritte Argument eine Liste von Optionen. In diesem Fall eine leere Liste.

def start_link do
GenServer.start_link(__MODULE__, :ok, [])
end

Anrufen und Casting von der öffentlichen API

Als nächstes müssen wir die öffentliche API für das Modul zur Verfügung stellen. Dies sind die Funktionen, die von anderen Modulen Ihrer Anwendung aufgerufen werden.

Die read/1-Funktion ruft die Call/2-Funktion des GenServer.module auf, um die Anfrage an den Prozess zu senden. Der Prozess blockiert, bis er eine Antwort vom Server erhalten hat. Das erste Argument ist die ProzessID. Das zweite der Term der für die Auswahl (Per Pattern-Matching) des Callback-Handle benötigt wird.

Die add/2-Funktion ruft die Cast/2-Funktion des GenServer.module auf. Diese Funktion wartet nicht auf die Antwort des Servers.

def read(pid) do
GenServer.call(pid, {:read})
end

def add(pid, item) do
GenServer.cast(pid, {:add, item})
end

Initialisierung des Servers

def init(:ok) do
{:ok, []}
end

Call Anfragen bearbeiten

Als nächstes behandeln wir die Call-Anfrage der API mit dem :read Term

def handle_call({:read}, _from, list) do
{:reply, list, list}
end

Cast Anfragen bearbeiten

Als nächstes behandeln wir die Cast-Anfrage der API mit dem :add Term

def handle_cast({:add, item}, list) do
{:noreply, list ++ [item]}
end

Die Datei todo_list.ex sieht dann folgendermaßen aus.

defmodule TodoList do
use GenServer

# Client API

def start_link do
GenServer.start_link(__MODULE__, :ok, [])
end

def read(pid) do
GenServer.call(pid, {:read})
end

def add(pid, item) do
GenServer.cast(pid, {:add, item})
end

# Server Callbacks

def init(:ok) do
{:ok, []}
end

def handle_call({:read}, from, list) do
{:reply, list, list}
end

def handle_cast({:add, item}, list) do
{:noreply, list ++ [item]}
end
end

Iex

Jetzt im Terminal iex todo_list.ex aufrufen.

Den Server starten

iex> {:ok, pid} = ToDoList.start_link

Der Server antwortet mit {:ok, #PID<0.88.0> Jetzt kann die erste Aufgabe hinzugefügt werden.

iex(2)> ToDoList.add(pid, "Learn Elixir")
# Und eine zweite
iex(3)> ToDoList.add(pid, "Build a great app")

Nun lesen wir die Liste aus

iex(4)> TodoList.read(pid)

Und bekommen ["Learn Elixir", "Build a great app"]

https://github.com/Fulnir/GenServer-Beispiel

)
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade