class Rx::Middleware

Constants

DEFAULT_OPTIONS

Attributes

app[R]
deep_critical_checks[R]
deep_secondary_checks[R]
liveness_checks[R]
options[R]
readiness_checks[R]

Public Class Methods

new(app, liveness: [Rx::Check::FileSystemCheck.new], readiness: [Rx::Check::FileSystemCheck.new], deep_critical: [], deep_secondary: [], options: {}) click to toggle source
# File lib/rx/middleware.rb, line 9
def initialize(app,
               liveness:       [Rx::Check::FileSystemCheck.new],
               readiness:      [Rx::Check::FileSystemCheck.new],
               deep_critical:  [],
               deep_secondary: [],
               options:        {})
  @app = app
  @options = DEFAULT_OPTIONS.merge(options)
  @cache = cache_factory(@options)

  @liveness_checks = liveness
  @readiness_checks = readiness
  @deep_critical_checks = deep_critical
  @deep_secondary_checks = deep_secondary
end

Public Instance Methods

call(env) click to toggle source
# File lib/rx/middleware.rb, line 25
def call(env)
  unless health_check_request?(path(env))
    return app.call(env)
  end

  case path(env)
  when "/liveness"
    ok = check_to_component(liveness_checks).map { |x| x[:status] == 200 }.all?
    liveness_response(ok)
  when "/readiness"
    readiness_response(check_to_component(readiness_checks))
  when "/deep"
    @cache.cache("deep") do
      readiness = check_to_component(readiness_checks)
      critical  = check_to_component(deep_critical_checks)
      secondary = check_to_component(deep_secondary_checks)

      deep_response(readiness, critical, secondary)
    end
  end
end

Private Instance Methods

cache_factory(options) click to toggle source
# File lib/rx/middleware.rb, line 52
def cache_factory(options)
  unless options[:cache]
    return Rx::Cache::NoOpCache.new
  end

  Rx::Cache::InMemoryCache.new
end
check_to_component(check) click to toggle source
# File lib/rx/middleware.rb, line 92
def check_to_component(check)
  Array(check)
    .map { |check| Rx::Concurrent::Future.execute { check.check } }
    .map(&:value)
    .map { |r| { name: r.name, status: r.ok? ? 200 : 503, message: r.ok? ? "ok" : r.error, response_time_ms: r.timing } }
end
deep_response(readiness, critical, secondary) click to toggle source
# File lib/rx/middleware.rb, line 82
def deep_response(readiness, critical, secondary)
  status = (readiness.map { |x| x[:status] == 200 } + critical.map { |x| x[:status] == 200 }).all? ? 200 : 503

  [
    status,
    {"content-type" => "application/json"},
    [JSON.dump(status: status, readiness: readiness, critical: critical, secondary: secondary)]
  ]
end
health_check_request?(path) click to toggle source
# File lib/rx/middleware.rb, line 60
def health_check_request?(path)
  %w[/liveness /readiness /deep].include?(path)
end
liveness_response(is_ok) click to toggle source
# File lib/rx/middleware.rb, line 64
def liveness_response(is_ok)
  [is_ok ? 200 : 503, {}, []]
end
path(env) click to toggle source
# File lib/rx/middleware.rb, line 68
def path(env)
  env["PATH_INFO"] || env["REQUEST_PATH"] || env["REQUEST_URI"]
end
readiness_response(components) click to toggle source
# File lib/rx/middleware.rb, line 72
def readiness_response(components)
  status = components.map { |x| x[:status] == 200 }.all? ? 200 : 503

  [
    status,
    {"content-type" => "application/json"},
    [JSON.dump({status: status, components: components})]
  ]
end