OTP服务器
use的效果將OTP GenServer的行為添加到當(dāng)前模塊。這樣它就可以處理所有的回調(diào)函數(shù)。這也意味著我們不需要在模塊中定義所有的回調(diào)函數(shù)——該行為定義了所有默認(rèn)的回調(diào)函數(shù)。
當(dāng)客戶端調(diào)用服務(wù)器時(shí),GenServer調(diào)用接下來(lái)的hand_call函數(shù)。它接受:1、客戶端傳遞給調(diào)用的信息。2、客戶端的PID。3、服務(wù)器狀態(tài)。
其返回一個(gè)元組給OTP { :reply, current_number, current_number + 1 },reply告訴OTP需要回復(fù)客戶端,第二個(gè)是返回值,第三個(gè)定義了新的狀態(tài)。該狀態(tài)子在handle_call下次被調(diào)用時(shí)作為最后一個(gè)參數(shù)傳入。
啟動(dòng)服務(wù)器:
iex -S mix { :ok, pid } = GenServer.start_link(Sequence.Server, 100) #100是狀態(tài),相當(dāng)于該進(jìn)程的一個(gè)屬性。GenServer.call( pid, :next_number ) # 100 GenServer.call( pid, :next_number ) # 101start_link函數(shù)的行為類似于spawn_link。它要求GenServer創(chuàng)建一個(gè)新的進(jìn)程并與我們相關(guān)聯(lián),并傳遞了一個(gè)狀態(tài)值進(jìn)去。返回服務(wù)器的pid
call調(diào)用pid進(jìn)程里的handle_call函數(shù),將其第二個(gè)參數(shù)(:next_number )與handle_call的第一個(gè)參數(shù)做匹配。handle_call的第一個(gè)參數(shù)也可以是元組。
def handle_call({ :set_number, new_number}, _form, _current_number ) do{:reply, new_number, new_number } end然后這樣調(diào)用 GenServer.call(pid, {:set_number, 999} ) # 999?
cast
cast函數(shù)調(diào)用服務(wù)器,但不等待回復(fù)。cast發(fā)送給handle_cast,由于可能沒(méi)有相應(yīng),所以handle_cast只需要兩個(gè)參數(shù)。放棄了第二個(gè)代表客戶端pid的參數(shù)。其返回元組為{ :noreply, new_state }
defmodule Sequence.Server douse GenServerdef handle_call( :next_number, _from, current_number) do{ :reply, current_number, current_number + 1}enddef handle_cast({:increment_number, delta}, current_number) do{ :noreply, current_number + delta}end endGenServer.call(pid, :next_number) #100 GenServer.call(pid, :next_number) #101 GenServer.cast(pid, {:increment_number, 200}) # :ok GenServer.call(pid, :next_number) #302?
回調(diào)函數(shù)
init(start_arguments)。當(dāng)GenServer啟動(dòng)服務(wù)器時(shí)被調(diào)用,默認(rèn)將服務(wù)器狀態(tài)設(shè)置為出入?yún)?shù)的值。
handle_call(request, from, state)。客戶端使用GenServer.call(pid, request)時(shí)被調(diào)用。成功返回{ :reply, result, new_state }
handle_cast(request, state)。用于響應(yīng)GenServer.cast(pid, request)。成功的相應(yīng)是{ :noreply, new_state },也能返回{ :stop, reason, new_state }
handle_info(info, state)。用于處理call和cast以外的傳入消息。
terminate(reason, state)。當(dāng)服務(wù)器將終止時(shí)該函數(shù)被調(diào)用。
code_change(from_version, state, extra)。理由OTP替換正在運(yùn)行的服務(wù)器而無(wú)需停止整個(gè)系統(tǒng)。
format_status(reason, [pdict, state])。定制服務(wù)器的狀態(tài)顯示。
?
給進(jìn)程命名
啟動(dòng)服務(wù)器的時(shí)候加上 name:參數(shù) 。
{ :ok, pid } = GenServer.start_link(Sequence.Server, 100, name::seq) GenServer.call(:seq, :next_number)?
整理接口
defmodule Sequence douse GenServerdef start_link(current_number) doGenServer.start_link(__MODULE__, current_number, name: __MODULE__)enddef next_number doGenServer.call __MODULE__, next_numberenddef increment_number(delta) doGenServer.call __MODULE__, {:increment_number, delta}enddef handle_call( :next_number, _from, current_number) do{ :reply, current_number, current_number + 1}enddef handle_cast({:increment_number, delta}, current_number) do{ :noreply, current_number + delta}end end
?
轉(zhuǎn)載于:https://www.cnblogs.com/lr1402585172/p/11512363.html
總結(jié)