Class: Delayed::Monitor

Inherits:
Object
  • Object
show all
Includes:
Runnable
Defined in:
lib/delayed/monitor.rb

Constant Summary collapse

METRICS =
%w(
  count
  future_count
  locked_count
  erroring_count
  failed_count
  max_lock_age
  max_age
  working_count
  workable_count
  alert_age_percent
).freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Runnable

#start

Constructor Details

#initializeMonitor

Returns a new instance of Monitor.



20
21
22
23
24
# File 'lib/delayed/monitor.rb', line 20

def initialize
  @jobs = Job.group(:priority, :queue)
  @jobs = @jobs.where(queue: Worker.queues) if Worker.queues.any?
  @memo = {}
end

Class Method Details

.parse_utc_time(string) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/delayed/monitor.rb', line 49

def self.parse_utc_time(string)
  # Depending on Rails version & DB adapter, this will be either a String or a DateTime.
  # If it's a DateTime, and if connection is running with the `:local` time zone config,
  # then by default Rails incorrectly assumes it's in local time instead of UTC.
  # We use `strftime` to strip the encoded TZ info and re-parse it as UTC.
  #
  # Example:
  # - "2026-02-05 10:01:23"        -> DB-returned string
  # - "2026-02-05 10:01:23 -0600"  -> Rails-parsed DateTime with incorrect TZ
  # - "2026-02-05 10:01:23"        -> `strftime` output
  # - "2026-02-05 04:01:23 -0600"  -> Re-parsed as UTC and converted to local time
  string = string.strftime('%Y-%m-%d %H:%M:%S') if string.respond_to?(:strftime)

  ActiveSupport::TimeZone.new("UTC").parse(string)
end

.sql_now_in_utcObject



38
39
40
41
42
43
44
45
46
47
# File 'lib/delayed/monitor.rb', line 38

def self.sql_now_in_utc
  case ActiveRecord::Base.connection.adapter_name
  when 'PostgreSQL'
    "TIMEZONE('UTC', STATEMENT_TIMESTAMP())"
  when 'MySQL', 'Mysql2'
    "UTC_TIMESTAMP()"
  else
    "CURRENT_TIMESTAMP"
  end
end

Instance Method Details

#query_for(metric) ⇒ Object



34
35
36
# File 'lib/delayed/monitor.rb', line 34

def query_for(metric)
  send(:"#{metric}_grouped")
end

#run!Object



26
27
28
29
30
31
32
# File 'lib/delayed/monitor.rb', line 26

def run!
  @memo = {}
  ActiveSupport::Notifications.instrument('delayed.monitor.run', default_tags) do
    METRICS.each { |metric| emit_metric!(metric) }
  end
  interruptable_sleep(sleep_delay)
end