0
votes

I am new to elixir and distributed programming. I try the sample spawning a method from other node by Jose Valim example in Youtube. But it is not working and cannot found the right answer.

iex(bob@local)2> Node.spawn(:"[email protected]", fn -> Hello.world() end)
#PID<0.116.0>

22:05:12.657 [warn]  ** Can not start :erlang::apply,[#Function<20.128620087/0 in :erl_eval.expr/5>, []] on :"[email protected]" **

I try all the suggestion in this Distributed Elixir example doesn't work .ThePanuto said it was all about the IP. I also try Node.connect thing. But still i cant solved it. What did I missed?

1
Do you have a machine running under the name of alice.local? :) - Filip Haglund
Check out the example I give here: stackoverflow.com/questions/32152093/… - GavinBrelstaff
At first when i tried to follow exactly to the tutorial, --name alice without the local it throw an "need long name error". Then I try creating node with the local, it is worked. ~$ iex --name alice@local --cookie "secret" Erlang/OTP 21 [erts-10.1.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] Also aready tried your suggestion Gavin, Node.connect :"node@machinename2" also throw a "false" iex(alice@local)3> Node.connect :"[email protected]" false - bensisva

1 Answers

2
votes

There are two scenarios:

  • In order to connect two Elixir nodes that run on the same computer, open two terminal windows and try this:

    1. in terminal window #1:

      $ iex --sname alice
      Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] [dtrace]
      
      Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
      iex(alice@eugene-mbp)1>
      
    2. in terminal window #2:

      $ iex --sname bob
      Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] [dtrace]
      
      Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
      iex(bob@eugene-mbp)1>
      

    Here eugene-mbp is the hostname of my computer without the domain part. With the domain part it would look like this eugene-mbp.local.

  • In case you'd like to run the nodes on two separate computers but you only have one computer, you may want to try Docker. Open two terminal windows and try this:

    1. in terminal window #1:

      $ docker run -it --rm --name node1 --hostname node1 --network example elixir:1.7-alpine iex --sname alice --cookie secret
      Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] [dtrace]
      
      Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
      iex(alice@node1)1>
      
    2. in terminal window #2:

      $ docker run -it --rm --name node2 --hostname node2 --network example elixir:1.7-alpine iex --sname bob --cookie secret
      Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] [dtrace]
      
      Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
      iex(bob@node2)1>
      

Now let's come back to spawning a process from one node on the other. The following steps will be based on the run on the same computer example above.

In terminal window #1 run these commands:

iex(alice@eugene-mbp)1> Node.list()
[]
iex(alice@eugene-mbp)2> Node.ping(:"bob@eugene-mbp")
:pong
iex(alice@eugene-mbp)3> Node.list()
[:"bob@eugene-mbp"]

In the command sequence above we first see if nodes know about each other, and as a matter of fact they do not. Then we ping a "bob" node. Then we check once again if the nodes know each other, and now they do!

Now, let's define a module on the "bob" node. Open terminal #2, and write this:

iex(bob@eugene-mbp)1> defmodule Hello do
...(bob@eugene-mbp)1> def world do
...(bob@eugene-mbp)1> IO.puts "Hello, world!"
...(bob@eugene-mbp)1> end
...(bob@eugene-mbp)1> end
{:module, Hello,
 <<70, 79, 82, 49, 0, 0, 4, 40, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 140,
   0, 0, 0, 15, 12, 69, 108, 105, 120, 105, 114, 46, 72, 101, 108, 108, 111, 8,
   95, 95, 105, 110, 102, 111, 95, 95, 7, ...>>, {:world, 0}}

Finally, let's call this function we just defined from within "alice" node. Open terminal #1 and run it. Here's a full output:

iex(alice@eugene-mbp)4> Node.spawn(:"bob@eugene-mbp", fn -> Hello.world() end)
Hello, world!

#PID<10894.142.0>
iex(alice@eugene-mbp)5>