Class: Delayed::Priority
- Inherits:
-
Numeric
- Object
- Numeric
- Delayed::Priority
- Defined in:
- lib/delayed/priority.rb
Constant Summary collapse
- DEFAULT_NAMES =
A Delayed::Priority represents a value that exists within a named range. Here are the default ranges and their names:
0-9: interactive
10-19: user_visible 20-29: eventual
30+: reporting
Ranges can be customized. They must be positive and must include a name for priority >= 0. The following config will produce ranges 0-99 (high), 100-499 (medium) and 500+ (low):
> Delayed::Priority.names = { high: 0, medium: 100, low: 500 }
{ interactive: 0, # These jobs will actively hinder end-user interactions until they are complete, e.g. work behind a loading spinner user_visible: 10, # These jobs have end-user-visible side effects that will not obviously impact customers, e.g. welcome emails eventual: 20, # These jobs affect business process that are tolerant to some degree of queue backlog, e.g. syncing with other services reporting: 30, # These jobs are for processes that can complete on a slower timeline, e.g. daily report generation }.freeze
- DEFAULT_ALERTS =
Priorities can be mapped to alerting thresholds for job age (time since run_at), runtime, and attempts. These thresholds can be used to emit events or metrics. Here are the default values (for the default priorities):
Age Alerts ==========
interactive: 1 minute user_visible: 3 minutes eventual: 1.5 hours reporting: 4 hours
Run Time Alerts ======
interactive: 30 seconds user_visible: 90 seconds eventual: 5 minutes reporting: 10 minutes
Attempts Alerts =====
interactive: 3 attempts user_visible: 5 attempts eventual: 8 attempts reporting: 8 attempts
Alerting thresholds can be customized. The keys must match ‘Delayed::Priority.names`.
Delayed::Priority.alerts = {
high: { age: 30.seconds, run_time: 15.seconds, attempts: 3 }, medium: { age: 2.minutes, run_time: 1.minute, attempts: 6 }, low: { age: 10.minutes, run_time: 2.minutes, attempts: 9 },
}
{ interactive: { age: 1.minute, run_time: 30.seconds, attempts: 3 }, user_visible: { age: 3.minutes, run_time: 90.seconds, attempts: 5 }, eventual: { age: 1.5.hours, run_time: 5.minutes, attempts: 8 }, reporting: { age: 4.hours, run_time: 10.minutes, attempts: 8 }, }.freeze
Instance Attribute Summary collapse
-
#value ⇒ Object
readonly
Returns the value of attribute value.
Class Method Summary collapse
Instance Method Summary collapse
- #<=>(other) ⇒ Object
- #alert_age ⇒ Object
- #alert_attempts ⇒ Object
- #alert_run_time ⇒ Object
- #coerce(other) ⇒ Object
-
#initialize(value) ⇒ Priority
constructor
A new instance of Priority.
- #name ⇒ Object
Constructor Details
#initialize(value) ⇒ Priority
Returns a new instance of Priority.
119 120 121 122 123 |
# File 'lib/delayed/priority.rb', line 119 def initialize(value) super() value = self.class.names[value] if value.is_a?(Symbol) @value = value.to_i end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args) ⇒ Object (private)
156 157 158 159 160 161 162 |
# File 'lib/delayed/priority.rb', line 156 def method_missing(method_name, *args) if method_name.to_s.end_with?('?') && self.class.names.key?(method_name.to_s[0..-2].to_sym) method_name.to_s[0..-2] == to_s else super end end |
Instance Attribute Details
#value ⇒ Object (readonly)
Returns the value of attribute value.
114 115 116 |
# File 'lib/delayed/priority.rb', line 114 def value @value end |
Class Method Details
.alerts ⇒ Object
64 65 66 |
# File 'lib/delayed/priority.rb', line 64 def alerts @alerts || default_alerts end |
.alerts=(alerts) ⇒ Object
76 77 78 79 80 81 82 83 |
# File 'lib/delayed/priority.rb', line 76 def alerts=(alerts) if alerts unknown_names = alerts.keys - names.keys raise "unknown priority name(s): #{unknown_names}" if unknown_names.any? end @alerts = alerts&.sort_by { |k, _| names.keys.index(k) }&.to_h end |
.names ⇒ Object
60 61 62 |
# File 'lib/delayed/priority.rb', line 60 def names @names || default_names end |
.names=(names) ⇒ Object
68 69 70 71 72 73 74 |
# File 'lib/delayed/priority.rb', line 68 def names=(names) raise "must include a name for priority >= 0" if names && !names.value?(0) @ranges = nil @alerts = nil @names = names&.sort_by(&:last)&.to_h&.transform_values { |v| new(v) } end |
.ranges ⇒ Object
85 86 87 88 89 |
# File 'lib/delayed/priority.rb', line 85 def ranges @ranges ||= names.zip(names.except(names.keys.first)).each_with_object({}) do |((name, lower), (_, upper)), obj| obj[name] = (lower...(upper || Float::INFINITY)) end end |
Instance Method Details
#<=>(other) ⇒ Object
145 146 147 148 |
# File 'lib/delayed/priority.rb', line 145 def <=>(other) other = other.to_i if other.is_a?(self.class) to_i <=> other end |
#alert_age ⇒ Object
129 130 131 |
# File 'lib/delayed/priority.rb', line 129 def alert_age self.class.alerts.dig(name, :age) end |
#alert_attempts ⇒ Object
137 138 139 |
# File 'lib/delayed/priority.rb', line 137 def alert_attempts self.class.alerts.dig(name, :attempts) end |
#alert_run_time ⇒ Object
133 134 135 |
# File 'lib/delayed/priority.rb', line 133 def alert_run_time self.class.alerts.dig(name, :run_time) end |
#coerce(other) ⇒ Object
141 142 143 |
# File 'lib/delayed/priority.rb', line 141 def coerce(other) [self.class.new(other), self] end |
#name ⇒ Object
125 126 127 |
# File 'lib/delayed/priority.rb', line 125 def name @name ||= self.class.ranges.find { |(_, r)| r.include?(to_i) }&.first end |