Class: Flightdeck::JobRow
- Inherits:
-
Object
- Object
- Flightdeck::JobRow
- Defined in:
- app/models/flightdeck/job_row.rb
Overview
One row of a jobs list. Deliberately dumb: JobsQuery assembles these from bounded queries and the view asks them formatting questions.
Constant Summary collapse
- EXECUTION_MODELS =
Every table a job can be sitting in, in the order we report them. A job is only ever in one of these at a time, but we probe all five so a row is never silently mislabelled during a transition.
{ ready: "SolidQueue::ReadyExecution", scheduled: "SolidQueue::ScheduledExecution", in_progress: "SolidQueue::ClaimedExecution", blocked: "SolidQueue::BlockedExecution", failed: "SolidQueue::FailedExecution" }.freeze
Instance Attribute Summary collapse
-
#args_preview ⇒ Object
readonly
Returns the value of attribute args_preview.
-
#error_summary ⇒ Object
readonly
Returns the value of attribute error_summary.
-
#execution ⇒ Object
readonly
Returns the value of attribute execution.
-
#job ⇒ Object
readonly
Returns the value of attribute job.
-
#process ⇒ Object
readonly
Returns the value of attribute process.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
Class Method Summary collapse
-
.annotate(job_ids) ⇒ Object
Resolves the state of an already-loaded page of jobs with one
WHERE job_id IN (page_ids)lookup per executions table. - .model_for(state) ⇒ Object
-
.state_for(job, annotation) ⇒ Object
How a job's state is derived, in one place:
finished_atwins, then whichever execution tableannotatefound the job in, then :unknown for the transition window where a job is between tables.
Instance Method Summary collapse
- #active_job_id ⇒ Object
-
#attempts ⇒ Object
Attempt number, when ActiveJob recorded one in the serialized payload.
- #class_name ⇒ Object
- #concurrency_key ⇒ Object
- #discardable? ⇒ Boolean
-
#due_at ⇒ Object
The moment the job first became eligible to run — what "waiting" is measured from, so a job scheduled for next week is not reported as having waited a week.
- #enqueued_at ⇒ Object
- #execution_started_at ⇒ Object
- #failed? ⇒ Boolean
- #failed_at ⇒ Object
- #finished_at ⇒ Object
- #id ⇒ Object
-
#initialize(job:, state:, execution: nil, args_preview: nil, error_summary: nil, process: nil) ⇒ JobRow
constructor
A new instance of JobRow.
- #priority ⇒ Object
- #queue_name ⇒ Object
- #scheduled_at ⇒ Object
Constructor Details
#initialize(job:, state:, execution: nil, args_preview: nil, error_summary: nil, process: nil) ⇒ JobRow
Returns a new instance of JobRow.
58 59 60 61 62 63 64 65 |
# File 'app/models/flightdeck/job_row.rb', line 58 def initialize(job:, state:, execution: nil, args_preview: nil, error_summary: nil, process: nil) @job = job @state = state @execution = execution @args_preview = args_preview @error_summary = error_summary || ErrorSummary.none @process = process end |
Instance Attribute Details
#args_preview ⇒ Object (readonly)
Returns the value of attribute args_preview.
56 57 58 |
# File 'app/models/flightdeck/job_row.rb', line 56 def args_preview @args_preview end |
#error_summary ⇒ Object (readonly)
Returns the value of attribute error_summary.
56 57 58 |
# File 'app/models/flightdeck/job_row.rb', line 56 def error_summary @error_summary end |
#execution ⇒ Object (readonly)
Returns the value of attribute execution.
56 57 58 |
# File 'app/models/flightdeck/job_row.rb', line 56 def execution @execution end |
#job ⇒ Object (readonly)
Returns the value of attribute job.
56 57 58 |
# File 'app/models/flightdeck/job_row.rb', line 56 def job @job end |
#process ⇒ Object (readonly)
Returns the value of attribute process.
56 57 58 |
# File 'app/models/flightdeck/job_row.rb', line 56 def process @process end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
56 57 58 |
# File 'app/models/flightdeck/job_row.rb', line 56 def state @state end |
Class Method Details
.annotate(job_ids) ⇒ Object
Resolves the state of an already-loaded page of jobs with one
WHERE job_id IN (page_ids) lookup per executions table. Returns
{ job_id => { state:, execution_id:, process_id: } }.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'app/models/flightdeck/job_row.rb', line 37 def annotate(job_ids) job_ids = Array(job_ids).compact.uniq return {} if job_ids.empty? EXECUTION_MODELS.each_with_object({}) do |(state, model_name), found| model = model_name.constantize columns = [ :id, :job_id ] columns << :process_id if model.column_names.include?("process_id") model.where(job_id: job_ids).pluck(*columns).each do |values| job_id = values[1] next if found.key?(job_id) found[job_id] = { state: state, execution_id: values[0], process_id: values[2] } end end end |
.model_for(state) ⇒ Object
19 20 21 22 |
# File 'app/models/flightdeck/job_row.rb', line 19 def model_for(state) name = EXECUTION_MODELS[state.to_sym] name && name.constantize end |
.state_for(job, annotation) ⇒ Object
How a job's state is derived, in one place: finished_at wins, then
whichever execution table annotate found the job in, then :unknown
for the transition window where a job is between tables.
27 28 29 30 31 32 |
# File 'app/models/flightdeck/job_row.rb', line 27 def state_for(job, annotation) return :finished if job.finished_at.present? return annotation[:state] if annotation :unknown end |
Instance Method Details
#active_job_id ⇒ Object
71 |
# File 'app/models/flightdeck/job_row.rb', line 71 def active_job_id = job.active_job_id |
#attempts ⇒ Object
Attempt number, when ActiveJob recorded one in the serialized payload. We only ever see a truncated prefix of the arguments, so this is best-effort by design and returns nil rather than guessing.
98 99 100 101 |
# File 'app/models/flightdeck/job_row.rb', line 98 def attempts value = args_preview.to_s[/"executions"\s*:\s*(\d+)/, 1] value && value.to_i + 1 end |
#class_name ⇒ Object
68 |
# File 'app/models/flightdeck/job_row.rb', line 68 def class_name = job.class_name |
#concurrency_key ⇒ Object
72 |
# File 'app/models/flightdeck/job_row.rb', line 72 def concurrency_key = job.concurrency_key |
#discardable? ⇒ Boolean
78 |
# File 'app/models/flightdeck/job_row.rb', line 78 def discardable? = state != :in_progress |
#due_at ⇒ Object
The moment the job first became eligible to run — what "waiting" is measured from, so a job scheduled for next week is not reported as having waited a week.
83 84 85 |
# File 'app/models/flightdeck/job_row.rb', line 83 def due_at scheduled_at || enqueued_at end |
#enqueued_at ⇒ Object
73 |
# File 'app/models/flightdeck/job_row.rb', line 73 def enqueued_at = job.created_at |
#execution_started_at ⇒ Object
87 88 89 |
# File 'app/models/flightdeck/job_row.rb', line 87 def execution_started_at execution&.created_at if state == :in_progress end |
#failed? ⇒ Boolean
77 |
# File 'app/models/flightdeck/job_row.rb', line 77 def failed? = state == :failed |
#failed_at ⇒ Object
91 92 93 |
# File 'app/models/flightdeck/job_row.rb', line 91 def failed_at execution&.created_at if failed? end |
#finished_at ⇒ Object
75 |
# File 'app/models/flightdeck/job_row.rb', line 75 def finished_at = job.finished_at |
#id ⇒ Object
67 |
# File 'app/models/flightdeck/job_row.rb', line 67 def id = job.id |
#priority ⇒ Object
70 |
# File 'app/models/flightdeck/job_row.rb', line 70 def priority = job.priority |
#queue_name ⇒ Object
69 |
# File 'app/models/flightdeck/job_row.rb', line 69 def queue_name = job.queue_name |
#scheduled_at ⇒ Object
74 |
# File 'app/models/flightdeck/job_row.rb', line 74 def scheduled_at = job.scheduled_at |