7
votes

I have a very simple Elixir code sample I want to run on different nodes.

The first node is on my laptop, the second one is a Raspberry Pi, accessed via SSH.

The code is simple:

# node1@my-computer
defmodule Hello do
    def world, do: IO.puts "hello world"
end

# node2@raspberrypi
iex> Node.spawn_link :"node1@my-computer", fn -> Hello.world end

I expected that Node.spawn_link would print "hello world" on the Raspberry Pi, but instead it shows an error saying ** (EXIT from #PID<0.66.0>) no connect

On the same machine with two different iex instances this code works just fine.

I'm starting the IEx session on node1 with iex --sname node1 --cookie secret and on node2 with iex --sname node2 --cookie secret.

It's also worth noting that on my Raspberry Pi iex starts with this warning:

warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) Interactive Elixir (1.0.5) - press Ctrl+C to exit (type h() ENTER for help)

1
If you are calling node@raspberry from your computer (or vice-versa), you need to make sure you have declared somewhere that the host raspberry points to the raspberry IP, otherwise the runtime does not know how to find the "raspberry". Maybe a simpler way for now is to use IPs: Node.spawn_link :"[email protected]", .... Also use the other functions in Node to find more information about what is connected and what is not. - José Valim
I altered /etc/hosts to point raspberrypi to the local IP of the raspberry (192.168.1.103). Elixir complained that [error] ** System running to use fully qualified hostnames ** ** Hostname raspberrypi is illegal ** Ok, so I went and changed names to IP's: Node.spawn_link :"[email protected]", fn -> Hello.world end and it told me that ** Can not start :erlang::apply,[#Function<20.54118792/0 in :erl_eval.expr/5>, []] ([:link]) on :"[email protected]" ** I'm sure I'm missing something really simple here. - thepanuto
OK, I got it. It was the IP thing all the time, I just screwed things up. Thanks, José! - thepanuto

1 Answers

5
votes

I think you need to put the @ sign in the node-names to get them to be interpreted as separate networked machines

iex --name node@machinename1 --cookie mycookie
iex --name node@machinename2 --cookie mycookie

and then in the first iex shell connect the nodes:

Node.connect :"node@machinename2"

Note the colon syntax that make the node name into a elixir atom. The quotes are needed because of the @ sign. You might try machinenames with the raw ip addresses first before trying dns names, if you are having problems Nb: I use --name rather than your --sname