Adding code to child nodes

Hi!
I have been able to figure out how to spawn child nodes, but I’m not able to make the child nodes do anything. This is my current code:

:os.cmd('epmd -daemon')
    {:ok, parent} = Node.start(:parent@localhost, :shortnames)
:child.start(:localhost, 'child_1')

Spawning a function in the child node results in an error:

Node.spawn(:child_1@localhost, fn -> IO.puts "test" end)

IO.puts appears as undefined for the child node. How do i load code into child nodes?

1 Like

Problem there is that slave node was spawned without any extra libraries outside the Erlang standard distribution. That mean that module IO (Elixir.IO to be exact) do not exists on that module. With save module started like this you can use only Erlang standard library, so to achieve what you want you need to use fn -> :io.format("test") end.

1 Like

Okay, say I’ve created a module in my mix project, and I want my slave to run that code. How do i load the code into the slave node?

You either add Elixir and your application to load path or you need to send binary representation of the module to the slave and load it there.

I tried using some of the functions in the :code module to load, but it doesn’t seem to work.
I think this one is only for the master node:

:code.load_module(ExampleModule)

There was also this one:

:code.add_path(path)

Which only seems to work locally for my node. Where should i proceed?
(Node.spawning load_module() did not work either)

A good example might be to checkout what Phoenix does in its pubsub test suite which includes some multi node cases https://github.com/phoenixframework/phoenix_pubsub/blob/master/test/phoenix/distributed_pubsub_test.exs

3 Likes

Thanks for the help!
I had a look into some of the code, and was able to find the correct commands which let me load the code path into the slave:

:os.cmd('epmd -daemon')
Node.start(:master@localhost, :shortnames)
:slave.start(:localhost, 'slave')
:rpc.block_call(:test@localhost, :code, :add_paths, [:code.get_path()])
...
Node.spawn(:slave@localhost, fn -> IO.puts "test" end)
...
#PID<10741.85.0>
iex(master@localhost)9> test

It worked!

1 Like