Class: RoundhouseUi::DashboardController
- Inherits:
-
ApplicationController
- Object
- ActionController::Base
- ApplicationController
- RoundhouseUi::DashboardController
- Defined in:
- app/controllers/roundhouse_ui/dashboard_controller.rb
Overview
The dashboard reads through the backend port — no models of ours, no storage of ours. Everything here comes out of Redis via Sidekiq::Stats / Sidekiq::Queue.
Constant Summary
Constants inherited from ApplicationController
ApplicationController::AUDIT_VERBS
Instance Method Summary collapse
- #show ⇒ Object
-
#stats ⇒ Object
Polled by the dashboard for live counts (same approach Sidekiq Web uses — cheap JSON, no WebSocket/build step required).
Methods inherited from ApplicationController
allow_in_read_only, guard_in_read_only, #redirect_to, requires_capability
Instance Method Details
#show ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'app/controllers/roundhouse_ui/dashboard_controller.rb', line 5 def show @stats = backend.stats # queue_summaries, not queues: the raw objects differ per backend and older # SolidQueue::Queue has no #latency, so the dashboard 500'd on solid_queue 1.0.0 # as soon as one queue existed. Summaries are ours, batched, and uniform. @queues = backend.queue_summaries @metrics = Metrics.new(stats: @stats) @health = Health.new(stats: @stats, queues: @queues, metrics: @metrics) # Highest-signal slices for the overview, from data we already read. @top_errors = ErrorGroups.new(limit: 200).call.groups.first(5) @problem_queues = @queues.select { |q| q.latency > 5 }.sort_by { |q| -q.latency }.first(5) # Daily counts Sidekiq already keeps (#61). One read on render, not on the # poll — a six-month window is not something to re-fetch every few seconds. @history_days = History.clamp(params[:history].presence || History::DEFAULT_DAYS) @history = History.days(@history_days) @typical_failure_rate = History.typical_failure_rate(@history) end |
#stats ⇒ Object
Polled by the dashboard for live counts (same approach Sidekiq Web uses — cheap JSON, no WebSocket/build step required).
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'app/controllers/roundhouse_ui/dashboard_controller.rb', line 25 def stats s = backend.stats # queues was already loaded here for the count, so the names ride along # free — the command palette uses them to tell a queue name from a plain # search term without adding a Redis call to every page render. # queue_summaries, not queues: Sidekiq::Queue#size issues its own LLEN, so # reading a depth per queue off `queues` would put one round-trip per queue # on the endpoint every open tab hits every few seconds — the same N+1 that # was removed from the Queues page. This is two round-trips at any queue count. qs = backend.queue_summaries render json: { processed: s.processed, failed: s.failed, enqueued: s.enqueued, busy: s.workers_size, scheduled: s.scheduled_size, retries: s.retry_size, dead: s.dead_size, queues: qs.size, # Names ride along as the keys. They used to be sent separately as well, # which meant every queue name appeared twice in one response — 40KB per # poll per open tab on a 500-queue app, half of it duplicated. queue_depths: qs.to_h { |q| [ q.name, q.size ] }, # Total worker threads, for the capacity figure (#36). workers_size is # threads *busy right now*, which is a different number and goes to zero # on an idle fleet — dividing by it would claim infinite capacity. concurrency: backend.respond_to?(:concurrency) ? backend.concurrency : nil } end |