什么是GenServer?
defmodule GenServer do
@moduledoc """
A behaviour module for implementing the server of a client-server relation.
A GenServer is a process like any other Elixir process and it can be used
to keep state, execute code asynchronously and so on. The advantage of using
a generic server process (GenServer) implemented using this module is that it
will have a standard set of interface functions and include functionality for
tracing and error reporting. It will also fit into a supervision tree.
是 generic server 的缩写, 意为通用服务器. 这个模块里包含了所有实现一个服务器所需的最基本的函数.
GenServer的工作原理是什么?
本质就是客户端发送请求, 服务器做出相应动作.
GenServer模块中有哪些基本函数?
@callback init(args :: term) ::
{:ok, state} |
{:ok, state, timeout | :hibernate} |
:ignore |
{:stop, reason :: any} when state: any
回调函数initial/1
, 作用是确定服务器初始化时的状态.
@callback handle_call(request :: term, from, state :: term) ::
{:reply, reply, new_state} |
{:reply, reply, new_state, timeout | :hibernate} |
{:noreply, new_state} |
{:noreply, new_state, timeout | :hibernate} |
{:stop, reason, reply, new_state} |
{:stop, reason, new_state} when reply: term, new_state: term, reason: term
回调函数handle_call/3
, 作用是处理客户端发来的call消息.
@callback handle_cast(request :: term, state :: term) ::
{:noreply, new_state} |
{:noreply, new_state, timeout | :hibernate} |
{:stop, reason :: term, new_state} when new_state: term
回调函数handle_cast/2
, 用于处理客户端发来的cast消息.
@callback handle_info(msg :: :timeout | term, state :: term) ::
{:noreply, new_state} |
{:noreply, new_state, timeout | :hibernate} |
{:stop, reason :: term, new_state} when new_state: term
回调函数handle_info/2
, 用于处理所有其它消息(例如服务器内部信息).
@callback terminate(reason, state :: term) ::
term when reason: :normal | :shutdown | {:shutdown, term} | term
回调函数terminate/2
, 用于关闭服务器.
@callback code_change(old_vsn, state :: term, extra :: term) ::
{:ok, new_state :: term} |
{:error, reason :: term} when old_vsn: term | {:down, term}
回调函数code_change/3
, 用于对服务器上的代码进行热更新.
@spec start_link(module, any, options) :: on_start
函数start_link/3
, 用于新建一个与当前进程绑定的服务器, 若当前进程终结, 服务器也会随之关闭.
@spec start(module, any, options) :: on_start
函数start/3
, 和上面的差不多, 只是没有绑定.
@spec stop(server, reason :: term, timeout) :: :ok
函数stop/3
, 给服务器发送一个停止消息, 附带理由.
@spec call(server, term, timeout) :: term
函数call/3
, 向服务器发送一个异步的请求, 并等待回复.
@spec cast(server, term) :: :ok
函数cast/2
, 发送一个同步的请求.
@spec abcast([node], name :: atom, term) :: :abcast
函数abcast/3
, 对特定节点上的所有注册名为name的服务器发送cast消息.
@spec multi_call([node], name :: atom, term, timeout) ::
{replies :: [{node, term}], bad_nodes :: [node]}
函数multi_call/3
, 对特定节点上的所有注册名为name的服务器发送call消息.
@spec reply(from, term) :: :ok
函数reply/2
, 回复一个客户端.
@spec whereis(server) :: pid | {atom, node} | nil
函数whereis/1
, 返回服务器进程的pid, 或服务器名称.