次のようにノード間関数呼び出し (rpc) をテストしていました。
defmodule RpcTest do
def run do
Task.Supervisor.async( {DBServer.DistSupervisor, :'dbserver@hostname'}, fn -> "test" end)
|> Task.await
|> IO.inspect
end
end
次にdbserver
、ノードを実行し、 を呼び出しTask.Supervisor.start_link(name: DBServer.DistSupervisor)
てdbserver
rcp を受信し、別のノードで上記のコードを実行します。dbclient
以下のようにrpc を正しく実行できます。
dbserver
$ iex --sname dbserver --cookie a -S mix
Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Compiling 1 file (.ex)
Interactive Elixir (1.3.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(dbserver@hostname)1> Task.Supervisor.start_link(name: DBServer.DistSupervisor)
{:ok, #PID<0.101.0>}
iex(dbserver@hostname)2>
dbclient
$ elixir --sname dbclient --cookie a -S mix run -e RpcTest.run
"test"
ただし、コードを"test"
から"test test
" に変更した後、dbclient ノードが機能しません。
ここにエラーメッセージがあります
dbserver
iex(dbserver@hostname)2>
12:54:57.430 [error] Task #PID<0.110.0> started from {:"dbclient@hostname", #PID<13423.52.0>} terminating
** (BadFunctionError) expected a function, got: #Function<0.113878361/0 in RpcTest>
:erlang.apply/2
(elixir) lib/task/supervised.ex:94: Task.Supervised.do_apply/2
(elixir) lib/task/supervised.ex:45: Task.Supervised.reply/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Function: #Function<0.113878361/0 in RpcTest>
Args: []
dbclient
$ elixir --sname dbclient --cookie a -S mix run -e RpcTest.run
Compiling 1 file (.ex)
** (EXIT from #PID<0.52.0>) an exception was raised:
** (BadFunctionError) expected a function, got: #Function<0.113878361/0 in RpcTest.run/0>
:erlang.apply/2
(elixir) lib/task/supervised.ex:94: Task.Supervised.do_apply/2
(elixir) lib/task/supervised.ex:45: Task.Supervised.reply/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
さらに、手動で再起動した後も機能します。dbserver
興味深いことに、それはiex
どんなコードでも機能します。
$ iex --sname dbclient --cookie a -S mix
Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Compiling 1 file (.ex)
Interactive Elixir (1.3.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(dbclient@hostname)1> Task.Supervisor.async( {DBServer.DistSupervisor, :'dbserver@hostname'}, fn -> "test" end) |>
...(dbclient@hostname)1> Task.await |>
...(dbclient@hostname)1> IO.inspect
"test"
"test"
iex(dbclient@hostname)2> Task.Supervisor.async( {DBServer.DistSupervisor, :'dbserver@hostname'}, fn -> "test test" end) |>
...(dbclient@hostname)2> Task.await |>
...(dbclient@hostname)2> IO.inspect
"test test"
"test test"
私の質問は、
- ノード内の関数を別のノードから呼び出すのは間違った方法ですか?
- ノード間関数呼び出しを使用する場合、クライアント コードを変更するたびに呼び出し先ノードを再実行する必要がありますか?
iex
と の間で動作が異なるのはなぜelixir script
ですか?
コードとプロジェクト全体は、https ://github.com/ayamamori/rpc_test/blob/master/lib/rpc_test.ex にアップロードされています。
前もって感謝します!