-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ajout plug healthcheck spécifique pour le worker
- Loading branch information
1 parent
8f9d6d3
commit 68ae808
Showing
2 changed files
with
78 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
apps/transport/lib/transport_web/plugs/worker_healthcheck.ex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
defmodule TransportWeb.Plugs.WorkerHealthcheck do | ||
@moduledoc """ | ||
A plug for the worker. | ||
It displays: | ||
- when the app was started | ||
- the last attempt for Oban jobs | ||
- if the system is healthy | ||
The system is considered healthy if the app was started recently or | ||
if Oban attempted jobs recently. | ||
""" | ||
import Plug.Conn | ||
|
||
@app_start_waiting_delay {20, :minute} | ||
@oban_max_delay_since_last_attempt {60, :minute} | ||
|
||
def init(options), do: options | ||
|
||
def call(conn, opts) do | ||
{mod, fun} = opts[:if] | ||
|
||
if apply(mod, fun, []) do | ||
status_code = if healthy_state?(), do: 200, else: 503 | ||
|
||
conn | ||
|> put_resp_content_type("text/plain") | ||
|> send_resp(status_code, """ | ||
UP (WORKER-ONLY) | ||
App start time: #{app_start_datetime()} | ||
App started recently?: #{app_started_recently?()} | ||
Oban last attempt: #{oban_last_attempted_at()} | ||
Oban attempted jobs recently?: #{oban_attempted_jobs_recently?()} | ||
Healthy state?: #{healthy_state?()} | ||
""") | ||
|> halt() | ||
else | ||
conn | ||
end | ||
end | ||
|
||
def healthy_state? do | ||
app_started_recently?() or oban_attempted_jobs_recently?() | ||
end | ||
|
||
def app_started_recently? do | ||
start_datetime = app_start_datetime() | ||
{delay, unit} = @app_start_waiting_delay | ||
DateTime.before?(DateTime.utc_now(), DateTime.add(start_datetime, delay, unit)) | ||
end | ||
|
||
def app_start_datetime do | ||
Transport.Cache.fetch(app_start_datetime_cache_key_name(), fn -> DateTime.utc_now() end, expire: nil) | ||
end | ||
|
||
def app_start_datetime_cache_key_name, do: "#{__MODULE__}::app_start_datetime" | ||
|
||
def oban_attempted_jobs_recently? do | ||
oban_last_attempt = oban_last_attempted_at() | ||
{delay, unit} = @oban_max_delay_since_last_attempt | ||
DateTime.before?(oban_last_attempt, DateTime.add(oban_last_attempt, delay, unit)) | ||
end | ||
|
||
def oban_last_attempted_at do | ||
%Postgrex.Result{rows: [[delay]]} = | ||
DB.Repo.query!(""" | ||
SELECT MAX(attempted_at) | ||
FROM oban_jobs | ||
WHERE state = 'completed' | ||
""") | ||
|
||
case delay do | ||
nil -> DateTime.new!(~D[1970-01-01], ~T[00:00:00.000], "Etc/UTC") | ||
%NaiveDateTime{} = nt -> DateTime.from_naive!(nt, "Etc/UTC") | ||
end | ||
end | ||
end |