Class: Karst::Web::Middleware
- Inherits:
-
Object
- Object
- Karst::Web::Middleware
- Defined in:
- lib/karst/web/middleware.rb
Overview
Owns Karst's development-only HTTP evidence surface directly at the Rack boundary, rather than through a Rails engine. An engine would mount routes, load ActionView, and integrate into the host application's controller stack; Karst needs none of that to answer "what evidence does Karst currently hold," and all of it would blur the line between Karst's own page and the host application it is inspecting.
Beyond serving /karst itself, this middleware also gives every other development HTML response a tiny link back into /karst, already scoped to the controller/action that produced it (see Badge). Karst sees a request before Rails routes it, so the controller/action that will eventually handle it is not yet known -- that evidence only exists once ActionController has actually dispatched the request, and is captured here via a real process_action.action_controller notification rather than guessed from the request path. Request-local state, not global mutable state, carries that evidence from the notification callback (which fires nested inside @app.call, on whatever thread or fiber is serving this request) back out to the code injecting the badge, so concurrent Puma requests never cross-contaminate each other's context. rubocop:disable Metrics/ClassLength
Class Method Summary collapse
-
.ensure_context_capture! ⇒ Object
One subscription for the process lifetime of this middleware class, regardless of how many instances Rack::Builder creates: the notification is process-wide by nature, and its callback only ever writes into the current thread/fiber's own IsolatedExecutionState slot, so a single subscription safely serves every request.
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app) ⇒ Middleware
constructor
A new instance of Middleware.
Constructor Details
#initialize(app) ⇒ Middleware
Returns a new instance of Middleware.
59 60 61 62 63 |
# File 'lib/karst/web/middleware.rb', line 59 def initialize(app) @app = app @locality = Locality.new self.class.ensure_context_capture! end |
Class Method Details
.ensure_context_capture! ⇒ Object
One subscription for the process lifetime of this middleware class, regardless of how many instances Rack::Builder creates: the notification is process-wide by nature, and its callback only ever writes into the current thread/fiber's own IsolatedExecutionState slot, so a single subscription safely serves every request.
314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/karst/web/middleware.rb', line 314 def ensure_context_capture! @context_capture_mutex ||= Mutex.new @context_capture_mutex.synchronize do next if @context_capture_installed ActiveSupport::Notifications.subscribe("process_action.action_controller") do |*args| capture_context(args.last) end @context_capture_installed = true end end |
Instance Method Details
#call(env) ⇒ Object
65 66 67 68 69 70 71 |
# File 'lib/karst/web/middleware.rb', line 65 def call(env) return call_owned(env) if owned?(env) return @app.call(env) unless development? && @locality.local?(env["REMOTE_ADDR"]) call_with_badge(env) end |