require 'heartcheck/caching_app/cache' # A rack middleware to wrap around {Heartcheck::App} in a cache # Mount an instance of this class passing an app or `use` this in Rack. # This accepts an optional ttl for the cache that defaults to 300 seconds. module Heartcheck class CachingApp # Creates an instance of the middleware # # @param app [Heartcheck:App] the Rack app to wrap around # @param ttl [Integer] the time to cache the results in seconds # @param cache [Heartcheck::CachingApp::Cache] the cache instance to use # The cache will be created on first use if not supplied # # @return [#call] rack compatible middleware def initialize(app, ttl = 300, cache = nil) @app = app @ttl = ttl @cache = cache end # Invokes the middleware # # @param env [Hash] the rack request/environment # @return [Array] a rack compatible response def call(env) req = Rack::Request.new(env) controller = Heartcheck::App::ROUTE_TO_CONTROLLER[req.path_info] if controller && (result = cache.result(controller)) [200, { 'Content-type' => 'application/json' }, [result]] else @app.call(env) end end protected def cache @cache ||= start_cache(@ttl) end def start_cache(ttl) Heartcheck::CachingApp::Cache.new(Heartcheck::App::ROUTE_TO_CONTROLLER .values.uniq, ttl).tap(&:start) end end end