jbcaprell

jbcaprell

Why are children not given to the start argument in `mix.exs`?

The application/0 definition in a typical mix.exs file has an essential shape like this:

def application() do
  [mod: {MyApp, []}]
end

… where a tuple is given to the key :mod containing the application callback module and the start argument.

No idea why, but the thought occurred to me, why are an Application’s children usually defined in the Application module itself? In this example, for instance:

defmodule MyApp do
  use Application

  def start(_type, _init_arg) do
    children = [{Cluster.Supervisor, [topologies, [name: MyApp.Cluster]]}]]}]
    Supervisor.start_link(children, strategy: :one_for_one)
  end
end

… rather than passed to start/2 by the mix.exs file? So, I’ve spent the last several years thinking this was just a convention, except that it seems like libcluster won’t automatically connect nodes if I rely on mix.exs in this way. In a bare application, this structure:

def application do
  topologies = Application.get_env(:libcluster, :topologies) || []

  [
    mod: {
      MyOtherApp,
      [children: [{Cluster.Supervisor, [topologies, [name: MyApp.Cluster]]}]]
    }
  ]
end

… and …

defmodule MyApp do
  use Application

  def start(_type, init_arg) do
    Supervisor.start_link(init_arg[:children], strategy: :one_for_one)
  end
end

… which I would’ve assumed was equivalent, doesn’t work. So there’s definitely a difference here that I’m not catching, but I have no idea what it might be.

Marked As Solved

c4710n

c4710n

I guess the root reason is the config.


mix.exs is read at compile time, so:

def application do
  # will be determined at compile time.
  topologies = Application.get_env(:libcluster, :topologies) || [] 

  # ...
end

If you put libcluster config in config/config.exs:

# config/config.exs
config :libcluster,
  topologies: [
    # ...
  ] 

Then, it should work as you expected.

But, if you put libcluster config in config/runtime.exs:

# config/runtime.exs
config :libcluster,
  topologies: [
    # ...
  ] 

Bad things happen.


You can first try to check which config file your relevant configurations are located in. (Related docs - Mix — Mix v1.14.5)


EDIT: But, even if it works as you expected, you shouldn’t do that. Checkout what @benwilson512 said.

Also Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

I think you’re on the right track, but the other thing to emphasize is that really anything you’d want to do at runtime to configure children, or choose which children to run, won’t work properly in mix.exs. It’s also important to note that mix.exs is run prior to any dependencies being compiled because it’s the thing that defines the dependencies. So if you want to do any child spec that needs your dependencies, that’s out too.

Where Next?

Popular in Questions Top

albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
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
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New

Other popular topics Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
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
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
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
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New

We're in Beta

About us Mission Statement