TBK145

TBK145

Signal or hook at the end of starting a release

Hi everyone,

A while ago we had an issue with one of our production systems where the application was stuck in some kind of startup process. This meant some processes were started and others not. Our monitoring didn’t fully pick this up. So now we’re looking for a way that we know that a release is fully started.

We’re using mix release to build the packages and deploy them on servers where they’re managed by systemd.

Initially I looked at the BEAM, and did find :init.get_status/0. So I was thinking to use an rpc to check that in intervals, but I’d rather have something nicer.

Someone in the Elixir slack channel shared erlang-systemd with me. This looks really promising, but we’re using a umbrella application, and make multiple different releases with different sub-applications. So this makes it a bit hard to determine in which application Supervisor to put the ready signal. A solution to this would be to create a new application that just does this ready signal and make sure to include that application as the last started application of each different release. But that seems like a lot of overhead to me.

Ideally what I think I’m looking for is some kind of option on the boot script or the BEAM to call some kind of (systemd?) hook or a signal that is broadcasted when startup is completely done.

I’m interested in hearing more options or opinions on this!

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

This is pretty close to the K8s approach of liveliness vs readiness. When our app boots we have the Phoenix Endpoint child very early in the tree, but then we have two distinct health checks, /alive and /ready which maps to this code:

  def alive(conn, _params) do
    json(conn, %{alive: true})
  end

  def ready(conn, _params) do
    if Application.get_env(:my_app, :ready) do
      json(conn, %{ready: true})
    else
      send_resp(conn, 503, "")
    end
  end

The default value of ready is false in our config. Then at the bottom of our supervision tree we have a simple genserver which sets Application.put_env(:my_app, :ready, true), and also can message out somewhere if you want it to.

So at that point once that child runs GET /ready returns 200, and you know your app is fully booted. If you want that pushed somewhere then your genserver can do so. Handily if you trap exits this also gives you a nice flow on node shutdown, because that same genserver is now the first child to shutdown, so you can set /ready 503 and again notify out if you want.

Where Next?

Popular in Questions Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
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
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
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
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
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
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
sabri
Can someone explain the settings of pool_size of Ecto in config file? and what is the recommend size? Thanks
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New

Other popular topics Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
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
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement