[elixir! #0009] 漫话elixir源码之gen_server

什么是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的工作原理是什么?

[elixir! #0009] 漫话elixir源码之gen_server_第1张图片

本质就是客户端发送请求, 服务器做出相应动作.

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, 或服务器名称.

你可能感兴趣的:(elixir)