leifericf

leifericf

Automatically starting applications in the correct order

I’ve noticed that, in certain cases, the order in which applications start is significant.

Example from page 200 from Adopting Elixir:

It is also important to guarantee the :sasl application is started before the :logger application. Otherwise you will get duplicate reports.

Your mix.exs should look like this:

extra_applications: [:sasl, :logger]

In such cases, the programmer must ensure that applications are started in the correct order.

Perhaps it would be possible implement an improvement, such that applications are automatically started in the correct order? To make this work, I suppose each application would need to declare its own “startup dependencies” and/or “startup importance level.”

This would effectively move the responsibility of starting applications in the correct order from the programmer who uses the application, to the programmer who develops said application.

I don’t know whether this is doable; it’s just a thought that struck me whilst reading.

Most Liked

sasajuric

sasajuric

Author of Elixir In Action

The problem with this approach is that the application is not included in the application list, even though it’s required at runtime. This means you can’t build a proper OTP release with distillery (I’m presuming you’re not doing it now, but might want to do in the future). Any other tool which relies on the application list will also not work properly.

Instead of using runtime: false, you could instead add the vmstats application to the included_applications list:

# mix exs
# ...
def application do
  [
    included_applications: [:vmstats],
    # ...
  ]
end

And then somewhere in the supervision tree include %{id: :vmstats, start: {:vmstats, :start, [:normal, []]}} as a child. This will work properly with distillery, since application will be included in the release, but it won’t be started when the release is booted. Instead, the app is started in your own supervision tree.

Alternatively you could use vmstats normally (i.e. drop included_applications and runtime: false). In your app startup callback you could invoke something like Application.put_env(your_app, :statix_connected?, true) immediately after invoking Statix.connect, and then in your sink callback function push the data only if Application.get_env(your_app, :statix_connected?) == true.

michalmuskala

michalmuskala

AFAIK the sasl is no longer an issue in OTP 21, since the logs are now produced by the erlang’s new :logger that is always started. sasl is now only what it was always supposed to be - just tooling for releases.

rupurt

rupurt

@leifericf I’m running into a similar problem trying to send vmstats information to statsd via statix. I need to ensure that statix has connected to the statsd server before the vmstats application has started. The solution I came up with was to set the vmstats dependency to runtime: false and manually start it in my main application.

  defp deps do
    [
      # ...
      {:vmstats, "~> 2.3.0", runtime: false}
    ]
  end
  def start(_type, _args) do
    :ok = Strategies.Statix.connect()
    Application.start(:vmstats)

    Supervisor.start_link([], strategy: :one_for_one, name: MyApp.Supervisor)
  end

It would be fantastic if there was some way to specify the order in mix.exs without clobbering all applications by adding the applications key to def applications

Last Post!

rupurt

rupurt

@sasajuric thanks for the detailed insight. You’re correct, I’m not deploying my app yet but did plan on using distillery for an OTP release so this has saved me a wall of head bashing in the future :slight_smile:

Both approaches sound interesting and I can actually see me needing better error handling in the sink for when the statsd server is down etc… so I’ll probably go with that approach.

Cheers!

Where Next?

Popular in Discussions Top

AstonJ
Are there any Elixir or Erlang libraries that help with this? I’ve been thinking how streaming services like twitch have exploded recentl...
New
und0ck3d
Hello everyone! A few days ago I’ve created a topic here about how people were creating CMSs with Elixir and Phoenix. I’ve been studying...
New
PragTob
Hey everyone, this has been brewing in my head some time and it came up again while reading Adopting Elixir. GenServers, supervisors et...
New
PragTob
Hello everyone, I know we had quite some threads (read through lots of them) about background job processing but it remains a hotly deba...
New
lucaong
Hello Elixir and Nerves community, I have been working for a while on an open-source embedded key-value database for Elixir, that I call...
230 14350 124
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
fireproofsocks
I’ve been working on an Elixir project that has required a lot of scripting. I usually reach for Elixir because I like it more (and in th...
New

Other popular topics Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
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
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
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
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement