TL; DR은 :
방법은 RPC를 처리하기 위해 상기 타겟 노드 스폰.
토론
우리는 RPC 모듈의 코드를 살펴 경우, 우리가 disterl에 기본이되는 일반 노드 간 메시징 기능을 래핑 볼 :
https://github.com/erlang/otp/blob/master/lib/kernel/src/rpc.erl#L398-L403
-spec cast(Node, Module, Function, Args) -> true when
Node :: node(),
Module :: module(),
Function :: atom(),
Args :: [term()].
cast(Node, Mod, Fun, Args) when Node =:= node() ->
catch spawn(Mod, Fun, Args),
true;
cast(Node, Mod, Fun, Args) ->
gen_server:cast({?NAME,Node}, {cast,Mod,Fun,Args,group_leader()}),
true.
현재 일어나고있는 일은 캐스트가 현재 노드에서 호출 될 때 새 프로세스이 제공된 MFA와 함께 스폰됩니다. 처형되다. 대/소문자가 다른 노드에서 호출되는 경우 메시지는 gen_server:cast/2
을 통해 표시된 노드의 그룹 리더에게 전송되고 대상 노드의 그룹 리더는 MFA를 처리하는 프로세스를 생성합니다.
캐스트에 대한 처리 코드는 여기에 있습니다 :
https://github.com/erlang/otp/blob/master/lib/kernel/src/rpc.erl#L130-L139 당신은 이미 당신을 처리 다른 노드로 메시지를 파견하려는 알고 경우
-spec handle_cast(term(), state()) -> {'noreply', state()}.
handle_cast({cast, Mod, Fun, Args, Gleader}, S) ->
spawn(fun() ->
set_group_leader(Gleader),
apply(Mod, Fun, Args)
end),
{noreply, S};
handle_cast(_, S) ->
{noreply, S}. % Ignore !
, 다음 노드의 메쉬를 슈퍼 노드로 취급하고, rpc 모듈을 완전히 우회하여 gen_server 호출을 작성하거나 직접 전달할 수 있습니다. 물론 어떤 접근 방식을 사용하는 것이 취향과 아키텍처의 문제인지는 물론입니다.
그래서 node1이 node2에서 rpc를 수신 할 때마다 내가 읽었던 완전히 새로운 프로세스를 생성해야하기 때문에 rpc 통신을 많이 보내지 않는 것이 좋습니다. – Ryan
노드에 대한 미리 정의 된 정보를 얻고 gen_server를 보내려면 다른 방법을 제안하십시오. cast() - 이상적으로 1) 새로운 프로세스가 생성되지 않도록 (시간이 걱정되는) 풀을 사용하려는 경우 2) 의 메시지가 오면 동시성이 제한됩니다. 어떻게하면 프로세스 ID를 알 수 있습니까? 프로세스 id를 얻으려면 먼저 node2에서 node2의 grpoc_get_worker 형식을 참조해야합니다. 이 문제에 대해 일반적으로 받아 들여지는 해결책이 있습니까, 아니면 모두가 다르게하는 "수정"입니까? – Ryan
@ 라이언 사실, 나는 너에게 좋은 소식이있다! 얼랑 (Erlang)에서의 스폰 프로세스는 시간, 메모리 및 CPU면에서 매우 가볍습니다 *. 다른 노드와 통신 할 때 발생하는 네트워크 통신 및 대기 시간은'rex' 작업보다 훨씬 비쌉니다. 따라서 상대방에'rex'가 하나 밖에 없더라도 요청에 너무 심하게 스팸 메일을 보낼 수 있습니다. 'rex' 작업의 오버 헤드는 무시할 수 있습니다. RPC가 적합한 경우 계산이 상당히 복잡하다면 캐스트 비용은 오버 헤드 우려가 가장 적습니다. – zxq9