Class: QueuePulse::Source::SolidQueue

Inherits:
Source
  • Object
show all
Defined in:
lib/queue_pulse/source/solid_queue.rb

Overview

Reads the real Solid Queue tables, read-only. All access goes through the solid_queue gem's own ActiveRecord models when present. Every method is defensive: if the schema isn't there yet, #available? returns false and the monitor skips all checks (Requirements US-2.4, US-7.5).

Instance Method Summary collapse

Instance Method Details

#available?Boolean

Returns:

  • (Boolean)


10
11
12
13
14
15
16
# File 'lib/queue_pulse/source/solid_queue.rb', line 10

def available?
  return false unless defined?(::SolidQueue::Job)

  ::SolidQueue::Job.connection.data_source_exists?("solid_queue_failed_executions")
rescue StandardError
  false
end

#failed_count_since(since_id) ⇒ Object



40
41
42
# File 'lib/queue_pulse/source/solid_queue.rb', line 40

def failed_count_since(since_id)
  ::SolidQueue::FailedExecution.where("id > ?", since_id).count
end

#failed_executions_since(since_id, limit:) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/queue_pulse/source/solid_queue.rb', line 18

def failed_executions_since(since_id, limit:)
  ::SolidQueue::FailedExecution
    .where("id > ?", since_id)
    .order(:id)
    .limit(limit)
    .includes(:job)
    .map do |fe|
      job = fe.job
      FailedRecord.new(
        id: fe.id,
        job_class: job&.class_name || "Unknown",
        queue_name: job&.queue_name || "unknown",
        error_message: extract_message(fe),
        failed_at: fe.created_at
      )
    end
end

#live_process_count(heartbeat_within:) ⇒ Object



72
73
74
75
# File 'lib/queue_pulse/source/solid_queue.rb', line 72

def live_process_count(heartbeat_within:)
  cutoff = now - heartbeat_within
  ::SolidQueue::Process.where("last_heartbeat_at >= ?", cutoff).count
end

#max_failed_execution_idObject



36
37
38
# File 'lib/queue_pulse/source/solid_queue.rb', line 36

def max_failed_execution_id
  ::SolidQueue::FailedExecution.maximum(:id)
end

#queue_statsObject



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/queue_pulse/source/solid_queue.rb', line 44

def queue_stats
  # Use ActiveRecord calculations (not a raw MIN pluck) so created_at comes
  # back as a properly time-zone-cast Time, not a naive DB string. Parsing
  # the string ourselves would misread UTC timestamps as local time and
  # invent a timezone-sized latency (e.g. +9h in JST).
  depths = ::SolidQueue::ReadyExecution.group(:queue_name).count
  oldest = ::SolidQueue::ReadyExecution.group(:queue_name).minimum(:created_at)
  depths.map do |queue_name, depth|
    QueueStat.new(queue_name: queue_name, depth: depth.to_i, oldest_enqueued_at: oldest[queue_name])
  end
end

#stuck_claimed_executions(older_than:) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/queue_pulse/source/solid_queue.rb', line 56

def stuck_claimed_executions(older_than:)
  cutoff = now - older_than
  ::SolidQueue::ClaimedExecution
    .where("created_at < ?", cutoff)
    .includes(:job)
    .map do |ce|
      job = ce.job
      ClaimedRecord.new(
        job_id: ce.job_id,
        job_class: job&.class_name || "Unknown",
        queue_name: job&.queue_name || "unknown",
        claimed_at: ce.created_at
      )
    end
end

#total_process_countObject



77
78
79
# File 'lib/queue_pulse/source/solid_queue.rb', line 77

def total_process_count
  ::SolidQueue::Process.count
end