code

2017年3月8日 星期三

Erlang筆記13 - OTP 1

什麼是Open Telecom Platform?

OTP是Ericsson為了大型分散式容錯系統寫的erlang library,這已經是standard erlang library。OTP包括完整的web browser, FTP server, .. 等等。

OTP特色就是Behavior framework。

OTP Behavior

OTP把常用的code pattern包成behavior application framework,只需要填入callback來handle event即可。其他所有fault tolerance, scalability, dynamic-code upgrade, 都不用擔心了,因為都被behavior framework implement好了,類似java j2ee container (我也不知道那是啥 哈哈)。

以下一步步示範怎麼從最簡單的server,長到OTP genserver裡面的server。

server1: 擁有callback的最可能簡單的server形式


這邊可以明顯看到我們在start function中接受一個Mod參數,此Mod參數必須implement
1. init(): 提供initial state
2. handle(): 就是真正的request handler

所以client先使用start來spawn一個process,然後用Name來bind這個server process的Pid。
然後再呼叫rpc來對sever下Request。注意rpc function也有 receive/end clause,這是對caller process來說安裝一個message receiver。

所以當Mod在loop中根據目前的State handle了Request之後,loop會遞迴呼叫自己,這時候Mod:handle()處裡的則是新的State1,所以 Mod本身不會有State,符合immutable的本性。

mod1

接下來該寫mod1。
可以看到server1.erl 其實就是個骨架而已,Mod1.erl才是真正的server implementation。



可以看到mod1的確implement了必要的 callbacks。所以這個server initial state是一個空的 dictionary,另外可以handle add和find兩種Request,並且接受新的Dict當作新的state,並且回傳改變過的Dict,相信dict:store()應該也是immutable implementation,意即回傳一個copy。

client實際上能看到的應該只有add和find function,handle function理論上client不該使用。

重點是:callback的implementation完全不用管concurrency model!!!!! 這很強大。

client1

在client process:

啟動service process:
2> server1:start(mod1, mod1).
true

這邊把Pid寫成mod1,其實是寫死的,因為我們在mod1.erl裡面也寫死Pid為mod1。


使用add
3> mod1:add("Sonny", "Office").

ok

使用find
4> mod1:find("Sonny").
{ok,"Office"}


就這樣,不過這樣其實蠻不直覺的interface!!!!


server2: transaction thru error handling

server1進化成serever2,藉由catch exception來確保"transaction semantics"執行。




可以看到在loop function裡面,如果執行了callback handle function失敗的話,loop會recursively calls itself with "OldState",所以下一個message來要求執行handle()仍然是使用OldState,也就是transaction失敗的話不會改變狀態。

但是如果沒有catch 任何exception 的話,loop就會recursively calls itself with NewState。


rpc function裡面也幫client新增了一個對crash atom的handler,直接exit,所以其實有改變了client 的behavior! 


Server 3: A Server with Hot Code Swapping

另一個可以神奇做到的是server code熱切換,意即不用把server給停下來。
只要改動loop:


可以看到當loop match到swap_code這個atom的時候,先送一個ack給message sender,然後loop很簡單的就靠recursion重啟了,並且使用了新的callback function,而且state不會改變!

這就是stateless的好處!!! 這在imperative server應該非常困難做到。


Server 4: A Becoming Server

這有點新時代的意味了?!

既然可以dynamic swap module,那甚至可以dynamic swap loop function!
一個本來在idle無所事事的server:


可以切換成以下的service:



只要送一個message給此process即可:



OK 以上別當真!

意思是上面的code / design 不是太好,只是作者要demonstrate distributed erlang的能力。總之直接使用OTP framework就可以了。


沒有留言:

張貼留言