Class: Usps::Support::HealthController
- Inherits:
-
ActionController::Base
- Object
- ActionController::Base
- Usps::Support::HealthController
- Defined in:
- app/controllers/usps/support/health_controller.rb
Overview
Base controller for external synthetic health probes (see the infrastructure repo's
doc/application_health_probes.md). Unlike Rails' /up (boot-only) and nginx's static
/instance-health-check, this exercises an app's critical dependencies and returns the sentinel
"HEALTHCHECK_OK
Host apps subclass this and declare which dependencies to probe with a CHECKS constant — a list
of symbols, each naming a #check_
class HealthController < Usps::Support::HealthController
CHECKS = %i[database redis hq_database imis].freeze
end
and route to it (get 'health' => 'health#show'). For a bespoke dependency, define a
#check_
Checks run on a background thread, not the request thread: a per-process refresher updates a cached snapshot every health_refresh_interval seconds and #show serves that snapshot, so a slow or wedged dependency can't tie up the Passenger worker pool. Each check also runs under health_check_timeout, and a raise or timeout reads as a failed check (its error captured) so the action always responds. See doc/health_check_refresh_design.md.
Per-component results (ok, latency, error) are handed to Usps::Support::HealthDiagnostics once per refresh which — when enabled — publishes them to CloudWatch so a past failure can be attributed to a specific component after it has recovered.
Inherits ActionController::Base directly — NOT the host's ApplicationController — to bypass
Devise auth, Pundit authorization, PaperTrail, and especially allow_browser, whose
modern-browser gate would 406 Route 53's non-browser prober and fail the probe for the wrong
reason.
Defined Under Namespace
Classes: CheckTimeout
Constant Summary collapse
- SENTINEL_PREFIX =
rubocop:disable Rails/ApplicationController
'HEALTHCHECK_OK'- CHECKS =
Symbols naming the dependency checks to run; each invokes the matching #check_
. Override per app by defining a CHECKS constant. Default probes the primary database only, which presumably every app needs. %i[database].freeze
Class Method Summary collapse
-
.health_monitor ⇒ Object
One monitor per concrete subclass, per process.
-
.reset_health_monitor! ⇒ Object
Drops the memoized monitor (stopping its thread).
Instance Method Summary collapse
Class Method Details
.health_monitor ⇒ Object
One monitor per concrete subclass, per process. Built lazily so the background thread starts after Passenger forks its workers (threads do not survive fork).
61 62 63 64 65 66 67 68 69 |
# File 'app/controllers/usps/support/health_controller.rb', line 61 def health_monitor klass = self @health_monitor ||= HealthMonitor.new( interval: health_refresh_interval, max_age: health_snapshot_max_age, background: health_background_refresh, runner: -> { klass.new.send(:run_and_record) } ) end |
.reset_health_monitor! ⇒ Object
Drops the memoized monitor (stopping its thread). For tests.
72 73 74 75 |
# File 'app/controllers/usps/support/health_controller.rb', line 72 def reset_health_monitor! @health_monitor&.stop @health_monitor = nil end |
Instance Method Details
#show ⇒ Object
78 79 80 81 82 83 |
# File 'app/controllers/usps/support/health_controller.rb', line 78 def show data = self.class.health_monitor.current return render_unavailable unless data render_health(data) end |