Class: SagaForge::Dashboard::SuspendedController
- Inherits:
-
BaseController
- Object
- ActionController::Base
- BaseController
- SagaForge::Dashboard::SuspendedController
- Defined in:
- app/controllers/saga_forge/dashboard/suspended_controller.rb
Overview
Instances (across every saga class) with at least one event that ran out of retries and landed in :failed, the saga is suspended pending a resume or compensate decision.
Constant Summary collapse
- CAP =
Bound the scan: at scale there can be a large backlog, so we examine at most CAP (most recently updated first) rather than the whole table.
500
Instance Method Summary collapse
Instance Method Details
#index ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'app/controllers/saga_forge/dashboard/suspended_controller.rb', line 11 def index @states = SagaForge::State.suspended.order(updated_at: :desc).limit(CAP).to_a @capped = @states.size == CAP # Single batched query keyed by saga_forge_state_id, grouped in Ruby, # instead of one query per row (N+1 at CAP=500 rows). A state can have # more than one failed event; earliest (ledger order) wins as "the" # failure to show. failed = SagaForge::Event.failed .where(saga_forge_state_id: @states.map(&:id)) .select(:saga_forge_state_id, :event_name, :error, :created_at, :id) .ledger_order .to_a @failed_event = failed.group_by(&:saga_forge_state_id).transform_values(&:first) # The list is cross-class, but bulk resume is scoped to one class (the # BulkRecoveryJob derives its scope from State.for_saga(klass)), so # offer one "resume all" button per distinct class present here. @saga_classes = @states.map(&:saga_class).uniq.sort end |