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
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 newinside theincluded_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:
- included_applications: http://erlang.org/doc/design_principles/included_applications.html
- synchronized start: http://erlang.org/doc/design_principles/included_applications.html#id82330
Also Liked
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 ![]()







