code

2017年3月3日 星期五

Erlang筆記12 - Distributed Programming 2

Remote Spawning

我們如何在遠端的node spawn process?
可以利用erlang spawn primitive的其中一個remote 版本:

-spec spawn(Node, Mod, Func, ArgList) -> Pid

以下是一個範例,我們希望達成在local node可以對遠端node Node spawn一個process,然後跑我們指定的module M的function F,以及其arguments list A

首先我們需要一個讓local node可以指定在遠端Node生出process的介面:

-module(remote_spawn).-export([start/1]).
start(Node) ->
  spawn(Node, fun() -> loop() end).

注意local node必須在呼叫remote_spawn:start()之後,用一個Pid去承接return回來的process id。

我們在start裡面,對遠端Node做spawn process的動作,執行loop這個function。
再來定義loop:

loop() ->
  receive    {rpc, Pid, M, F, A} ->
      Pid ! {self(), (catch apply(M, F, A))},
      loop()
  end.

loop會match {rpc, Pid, M, F, A} ,然後對此Pid發送spawn需要的參數訊息。

再來就是要包裹loop,加上sender的Pid,建立一個rpc function讓local node可以使用:

rpc(Pid, M, F, A) ->
  Pid ! {rpc, self(), M, F, A},
  receive    {Pid, Response} ->
      Response  end.
怎麼使用?我們先在同一台電腦上測試,建立兩個不同的erlang node:


Rita-Tsai:src sonnywang$ erl -sname gandalf -setcookie abc
Rita-Tsai:src sonnywang$ erl -sname bilbo -setcookie abc


然後在bilbo建立gandalf的process:
(bilbo@Rita-Tsai)6> Pid = remote_spawn:start('gandalf@Rita-Tsai').
<9993.80.0>

這個在gandalf的process建立了,而且成功回傳了Pid = <9993.80.0>
bilbo 可以對此remote process要求執行某個function,例如:

(bilbo@Rita-Tsai)8> remote_spawn:rpc(Pid, erlang, node, []).
'gandalf@Rita-Tsai'


gandalf回傳了gandalf node。(node()是回傳自己是哪一個node, nodes()回傳還有其他哪些nodes)。

或是要求print某個字串:

(bilbo@Rita-Tsai)12> remote_spawn:rpc(Pid, io, format, ["qq~n"]).
qq
ok


放在AWS兩個不同instance建立的nodes應該也會有同樣的效果。

沒有留言:

張貼留言