aeturnum

aeturnum

Confusing error when trying to start Genserver for multi-node testing

Hello,

I’m getting an odd error in a test I’m trying to write for what I imagined would be a simple multi-node test setup. Basically, in production we run a few different nodes and I’m trying to write some test to verify that the module works. Unfortunately, I ran into a problem where the GenServer (App.Cluster.TaskTests) was not running on the slave nodes and so I tried to start it. Here is where I ran into the odd error.

Here is the relevant part of my code (in a test function):

defmodule App.Cluster.TaskTests do
 use ExUnit.Case
 alias App.Cluster.Tasks

 setup_all do
   :net_kernel.monitor_nodes(true)
   :os.cmd('epmd -daemon')
   Node.start(:test@localhost, :shortnames) |> IO.inspect()

   children = ['child_1', 'child_2', 'child_3']

   for child <- children do
     IO.inspect(child)
     {:ok, node} = :slave.start_link(:localhost, child) |> IO.inspect()
     Node.spawn(node, Supervisor, :init, [[{App.Cluster.Tasks, {}}], strategy: :one_for_one]) |> IO.inspect()
   end

   on_exit(fn ->
     [node() | Node.list()]
     |> Enum.each(fn node -> Node.disconnect(node) end)
     :net_kernel.monitor_nodes(false)
   end)
 end

end

And here is the confusing error I get:

17:41:46.361 [error] Process #PID<37495.88.0> on node :child_1@localhost raised an exception
** (UndefinedFunctionError) function Supervisor.init/2 is undefined or private
    (elixir) Supervisor.init([{App.Cluster.Tasks, {}}], {:strategy, :one_for_one})

I get this error on each child, which of course causes any calls to the Tasks module to fail. I’m sure I’ve made some boneheaded mistake in setting this up (I’ve never worked with Nodes before), but I thought I would ask here and hope someone more experienced could spot my error.

Marked As Solved

aeturnum

aeturnum

I don’t know exactly what I was doing wrong in the code I posted, but I found an example of how to start up other nodes for tests in an older Elixir library that let me get my test working: swarm/test/support/cluster.ex at 4aee63d83ad5ee6ee095b38b3ff93a4dbb7c3400 · bitwalker/swarm · GitHub

Hopefully this will be helpful to anyone else in the same fix.

Also Liked

rvirding

rvirding

Creator of Erlang

I think the main problem is that you are using the Supervisor.init/2 function in the wrong way. If you check the docs here you will see it is basically intended to be used to return the supervisor spec in the init/1 callback function. This is called when you start a supervisor with Supervisor.start_link , you don’t explicitly spawn it yourself. This is true for all the OTP behaviours.

aceraxx

aceraxx

I ran into a similar issue while running tests in a similar environment.

What I think is happening is that the slave node is being started, but none of the modules from your master are loaded onto the code server for the slave. Here’s the blog post I read (in two parts) where I uncovered and figured out the solution: https://medium.com/@stavro/intro-slave-nodes-and-remote-code-loading-d1168bff7b20

Basically you have to point the slave node to the path where the .beam files live, so it can load it into its code server. This is done using :code.add_paths/1

Here’s what I did that seems to have solved the issue:

defmodule MyAppTest do

  use ExUnit.Case, async: true

  test "distributed test" do
    :net_kernel.start([:node1, :shortnames, 3000])
    {:ok, slave} = start_slave

    # rest of the test
  end

  defp start_slave do
    {:ok, hostname} = :inet.gethostname()
    {:ok, slave} = :slave.start(hostname, 'slave')
    :rpc.block_call(slave, :code, :add_paths, [:code.get_path])
    {:ok, slave}
  end
end

Where Next?

Popular in Questions Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
nobody
How to bind a phoenix app to a specific ip address? could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36128 110
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New

We're in Beta

About us Mission Statement