xadhoom

xadhoom

Best way to do synchronized start between umbrella apps using start_phases

I’m scratching my head on how to accomplish sync startup between umbrella apps, but no luck right now.

The base erlang reference (what I’m trying to obtain) is: Erlang -- Included Applications

I can use start_phases inside a single app to do things after the start callback and before the start returns , but I’m not able to sync several apps like the erlang reference does.

I’ve played with included_applications, extra and so on, but no luck.

Here’s a sample repo for what I’m testing: GitHub - xadhoom/sync_start_test: testing elixir umbrella apps synced start

What I’m obtaining is:

Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

SECONDARY: :go
PRIMARY: :init
PRIMARY: :go
Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

While I’m expecting to have: init & go from the primary app and then go from the secondary.
Maybe this is not (yet) possible with elixir?

Marked As Solved

xadhoom

xadhoom

After some help and pointers from @josevalim I was able to make it work.

The updated repo is always here: https://github.com/xadhoom/sync_start_test and the summary is:

  • create an umbrella containter
  • create your primary app inside the apps dir, as usual. Add some start_phases to it (will the correct callbacks implemened)
  • think about the apps that must be started as included_applications of the primary app. The primary app will become responsible of starting them
  • keep in mind that mix will always start all apps inside the apps/ path
  • create a new folder, like included_apps, at same level of apps/. Example: my_awesome_umbrella/included_apps
  • put into included_apps your secondary app, with a subset of primary app start_phases (remind the callbacks)

Now the setup that makes it work

  • in your primary app mix.exs change the mod value inside application/0 to mod: {:application_starter, [Primary.Application, []]}
  • add an included_application config inside application/0, like included_applications: [:secondary]
  • add a local path dep into deps/0 , like: {:secondary, path: "../../included_apps/secondary"}
  • start your application, you will see start_phases callbacks called in correct order

As @josevalim pointed out, being :secondary out of apps path, the usual mix commands like mix test or other umbrella conscious commands will not run for apps outside the apps/ tree, so they must be run manually.

Caveats:
In order to create new apps inside the included_apps/ path, there’re two possible ways:

  • create a new app using mix new inside the included_apps/ path and adjust all the needed project paths to point to umbrella:
  • build_path: “…/…/_build”,
  • config_path: “…/…/config/config.exs”,
  • deps_path: “…/…/deps”,
  • lockfile: “…/…/mix.lock”,
  • or, more easily, create it under the apps/ path and then move it

Links:

Also Liked

xadhoom

xadhoom

@peerreynders Uhm, no I was not insisting, it was the only way it worked.

Note that you’re starting from within your top_app folder, if you start it from the top level umbrella project it won’t work.

If I start a similar layout ( GitHub - xadhoom/sync_start_test at normal_umbrella ) from the primary app folder, yep, it works.

But if started from top folder, it will call twice the secondary callbacks (because of how mix starts umbrellas)

Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

SECONDARY: :go
PRIMARY: :init
PRIMARY: :go
SECONDARY: :go
Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

Said that, dunno what can be the best way.
Also thinking about releases of umbrella projects, how the startup sequence will work? I suspect that it will mimic the mix way, so my solution is better, but I’ve not tried it.

Unless there’s someway to handle the startup sequence in the release tools (I still have to investigate them).
If yes, for sure your solution is for sure better, since all “umbrella” enabled mix commands will continue to work :smiley:

Where Next?

Popular in Questions Top

yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
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
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
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement