TOP

elixir 高可用系列(二) GenServer(一)
2017-10-09 13:35:02 】 瀏覽:1938
Tags:

概述

如果我們需要管理多個進程,那么,就需要一個專門的 server 來集中監控和控制這些進程的狀態优乐棋牌app下载,啟停等。
OTP 平臺中的 GenServer 就是對這個 server 通用部分的抽象。

利用 GenServer 中已經提供的通用操作, 可以很方便的開發出可靠,健壯的程序。
下面首先通過一個示例演示 GenServer 的方便和強大之處,然后再對其進行介紹。

GenServer 示例

這是一個 GenServer 管理多個進程的示例,模擬控制各個進程的啟動优乐棋牌app下载,停止,以及狀態查詢。

defmodule ProcessMonitor do
  use GenServer
  #====================================================
  # api for clients
  #====================================================
  # start GenServer
  def start(data, opt \\ []) do
    GenServer.start_link(__MODULE__, data, opt)
  end
  # add process which is controled by this GenServer
  def process_add(server, name) do
    GenServer.call(server, {:add, name})
  end
  # get process status
  def process_status(server, name) do
    GenServer.call(server, {:status, name})
  end
  # start a process by name
  def process_start(server, name) do
    GenServer.cast(server, {:start, name})
  end
  # stop a process by name
  def process_stop(server, name) do
    GenServer.cast(server, {:stop, name})
  end
  #====================================================
  # callbacks for server
  #====================================================
  def init(data) do
    {:ok, data}
  end
  # handle status message synchronization
  def handle_call({:status, name}, _from, data) do
    val = Map.get(data, name, nil)
    {:reply, val, data}
  end
  # handle add message synchronization
  def handle_call({:add, name}, _from, data) do
    data = Map.put(data, name, "stopped")
    {:reply, name, data}
  end
  # handle start message asynchronization
  def handle_cast({:start, name}, data) do
    data = Map.put(data, name, "running")
    {:noreply, data}
  end
  # handle stop message asynchronization
  def handle_cast({:stop, name}, data) do
    data = Map.put(data, name, "stopped")
    {:noreply, data}
  end
end

上面代碼測試方法如下:

$ iex -S mix
Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Interactive Elixir (1.2.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> {:ok, server} = ProcessMonitor.start(Map.new)               # 創建 GenServer,并初始化一個 map 用于存儲此server管理的 process 信息
{:ok, #PID<0.87.0>}
iex(2)> ProcessMonitor.process_status(server, "process01")          # 創建 GenServer 后,默認沒有管理任何進程优乐棋牌app下载,所以沒有 process01 的信息
nil
iex(3)> ProcessMonitor.process_add(server, "process01")             # 給 GenServer 增加一個被管理進程 process01
"process01"
iex(4)> ProcessMonitor.process_status(server, "process01")          # 新加入的進程默認狀態是 stopped,示例代碼默認這么實現
"stopped"
iex(5)> ProcessMonitor.process_start(server, "process01")           # 啟動 process01
:ok
iex(6)> ProcessMonitor.process_status(server, "process01")          # process01 狀態變為 running
"running"
iex(7)> ProcessMonitor.process_stop(server, "process01")            # 停止 process01
:ok
iex(8)> ProcessMonitor.process_status(server, "process01")          # process01 狀態變為 stopped
"stopped"
iex(9)> ProcessMonitor.process_add(server, "process02")             # 再增加一個被管理進程 process02
"process02"
iex(10)> ProcessMonitor.process_start(server, "process02")          # 啟動 process02
:ok
iex(11)> ProcessMonitor.process_status(server, "process02")         # process02 狀態變為 running
"running"
iex(12)> ProcessMonitor.process_status(server, "  
		

請關注公眾號獲取更多資料



首頁 上一頁 1 2 下一頁 尾頁 1/2/2
】【打印繁體】【】【】 【】【】【】 【關閉】 【返回頂部
上一篇第二章 rabbitmq在mac上的安裝 下一篇elixir 高可用系列(三) GenEvent