Class: ChronoForge::Dashboard::RepetitionsQuery
- Inherits:
-
Object
- Object
- ChronoForge::Dashboard::RepetitionsQuery
- Defined in:
- app/queries/chrono_forge/dashboard/repetitions_query.rb
Overview
The per-iteration run logs of a single durably_repeat step.
These live on their own page rather than in the timeline: a long-running periodic step can accumulate many runs — mostly catch-up “tombstones” (expired/retried repetitions the engine marks failed and moves past) — and inlining them would both bury the timeline and load an unbounded set.
All access is keyed on ‘[workflow_id, step_name LIKE ’durably_repeat$step$%‘]`, which rides the unique `[workflow_id, step_name]` index as a range scan, so the summary counts and keyset pages stay cheap regardless of history depth.
Constant Summary collapse
- DEFAULT_PER =
50- MAX_PER =
200- CATCHUP_SCAN_CAP =
Bound the metadata scan used to count fast-forwarded ticks (see #summary): a pre-upgrade step may carry a long history of legacy per-tick rows.
1_000
Instance Attribute Summary collapse
-
#per ⇒ Object
readonly
Returns the value of attribute per.
-
#step ⇒ Object
readonly
Returns the value of attribute step.
-
#workflow ⇒ Object
readonly
Returns the value of attribute workflow.
Instance Method Summary collapse
- #has_next? ⇒ Boolean
- #has_prev? ⇒ Boolean
-
#initialize(workflow:, step:, before: nil, after: nil, per: DEFAULT_PER) ⇒ RepetitionsQuery
constructor
A new instance of RepetitionsQuery.
- #next_cursor ⇒ Object
- #prev_cursor ⇒ Object
- #records ⇒ Object
- #scope ⇒ Object
-
#summary ⇒ Object
Cheap roll-up (counts + last run) without loading run rows.
Constructor Details
#initialize(workflow:, step:, before: nil, after: nil, per: DEFAULT_PER) ⇒ RepetitionsQuery
Returns a new instance of RepetitionsQuery.
20 21 22 23 24 25 26 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 20 def initialize(workflow:, step:, before: nil, after: nil, per: DEFAULT_PER) @workflow = workflow @step = step @before = before.presence&.to_i @after = after.presence&.to_i @per = per.to_i.clamp(1, MAX_PER) end |
Instance Attribute Details
#per ⇒ Object (readonly)
Returns the value of attribute per.
28 29 30 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 28 def per @per end |
#step ⇒ Object (readonly)
Returns the value of attribute step.
28 29 30 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 28 def step @step end |
#workflow ⇒ Object (readonly)
Returns the value of attribute workflow.
28 29 30 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 28 def workflow @workflow end |
Instance Method Details
#has_next? ⇒ Boolean
35 36 37 38 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 35 def has_next? load @has_next end |
#has_prev? ⇒ Boolean
40 41 42 43 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 40 def has_prev? load @has_prev end |
#next_cursor ⇒ Object
45 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 45 def next_cursor = records.last&.id |
#prev_cursor ⇒ Object
46 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 46 def prev_cursor = records.first&.id |
#records ⇒ Object
30 31 32 33 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 30 def records load @records end |
#scope ⇒ Object
71 72 73 74 75 76 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 71 def scope @workflow.execution_logs.where( "step_name LIKE ?", "durably_repeat#{StepNameParser::DELIM}#{@step}#{StepNameParser::DELIM}%" ) end |
#summary ⇒ Object
Cheap roll-up (counts + last run) without loading run rows. Grouping by the ‘state` enum yields string-label keys (“completed”/“failed”), not integers.
‘tombstones` is the number of catch-up rows (cheap group count). `skipped_ticks` is the true number of skipped ticks: a fast-forward summary row collapses N expired ticks into one failed row tagged `fast_forwarded: N`, so it counts as N, while a legacy per-tick tombstone counts as 1. They diverge only once a fast-forward has happened.
57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'app/queries/chrono_forge/dashboard/repetitions_query.rb', line 57 def summary @summary ||= begin by_state = scope.group(:state).count failed = by_state["failed"].to_i { iterations: by_state.values.sum, completed: by_state["completed"].to_i, tombstones: failed, skipped_ticks: failed.zero? ? 0 : skipped_tick_count, last_run_at: scope.maximum(:started_at) } end end |