delayed 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/delayed/helpers/migration.rb +13 -18
- data/lib/delayed/monitor.rb +30 -21
- data/lib/delayed/version.rb +1 -1
- data/spec/delayed/__snapshots__/monitor_spec.rb.snap +687 -309
- data/spec/delayed/helpers/migration_spec.rb +33 -18
- data/spec/helper.rb +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4227961278ab7f1ed435e8357cbf83998ee6d1d597f981fc4d1ab92a0d1069fa
|
|
4
|
+
data.tar.gz: fd108cb072de3ec495d2713326821b231cfe8ffa153782a80f84da06d272ecfa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 36fd83967d57e3ae7d58a2edfceb790d35bcf3f9a49a9bf3de9e34c15528ba2c3ae36468c7847e8e49d7d90ca8b03ef1e39a62620257fb06cb8f321a5af0909e
|
|
7
|
+
data.tar.gz: df0443f6ca1f859e5b4155a0b38aa72310e0607f57c30ba31dcd0fda39825e0ae81903d0b019886c7405e607d1817f3733c47fbfed81b25cb897440cb2be8da8
|
|
@@ -20,13 +20,17 @@ module Delayed
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def upsert_index(*args, **opts)
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
with_retry_loop(**opts) do
|
|
24
|
+
dir(:up) { _add_or_replace_index(*args, **opts) }
|
|
25
|
+
dir(:down) { _drop_index_if_exists(*args, **opts) }
|
|
26
|
+
end
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
def remove_index_if_exists(*args, **opts)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
with_retry_loop(**opts) do
|
|
31
|
+
dir(:up) { _drop_index_if_exists(*args, **opts) }
|
|
32
|
+
dir(:down) { _add_or_replace_index(*args, **opts) }
|
|
33
|
+
end
|
|
30
34
|
end
|
|
31
35
|
|
|
32
36
|
RETRY_EXCEPTIONS = [
|
|
@@ -48,7 +52,7 @@ module Delayed
|
|
|
48
52
|
end
|
|
49
53
|
end
|
|
50
54
|
|
|
51
|
-
def with_timeouts(statement_timeout: 1.minute, lock_timeout: 5.seconds)
|
|
55
|
+
def with_timeouts(statement_timeout: 1.minute, lock_timeout: 5.seconds, **_opts)
|
|
52
56
|
dir(:both) { set_timeouts!(statement_timeout: statement_timeout, lock_timeout: lock_timeout) }
|
|
53
57
|
yield
|
|
54
58
|
ensure
|
|
@@ -61,24 +65,15 @@ module Delayed
|
|
|
61
65
|
index = _lookup_index(table, columns, **opts)
|
|
62
66
|
if index && !_index_matches?(index, **opts)
|
|
63
67
|
Delayed.logger.warn("Recreating index #{index.name} (is invalid or does not match desired options)")
|
|
64
|
-
|
|
68
|
+
remove_index(table, name: index.name)
|
|
65
69
|
end
|
|
66
|
-
|
|
70
|
+
opts = opts.except(:wait_timeout, :statement_timeout, :lock_timeout)
|
|
71
|
+
add_index(table, columns, **opts) if !index || !_index_matches?(index, **opts)
|
|
67
72
|
end
|
|
68
73
|
|
|
69
74
|
def _drop_index_if_exists(table, columns, **opts)
|
|
70
75
|
index = _lookup_index(table, columns, **opts)
|
|
71
|
-
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def _add_index(*args, **opts)
|
|
75
|
-
index_opts = opts.slice!(:wait_timeout, :statement_timeout, :lock_timeout)
|
|
76
|
-
with_retry_loop(**opts) { add_index(*args, **index_opts) }
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def _drop_index(table, name:, **opts)
|
|
80
|
-
opts.slice!(:wait_timeout, :statement_timeout, :lock_timeout)
|
|
81
|
-
with_retry_loop(**opts) { remove_index(table, name: name) }
|
|
76
|
+
remove_index(table, name: index.name) if index
|
|
82
77
|
end
|
|
83
78
|
|
|
84
79
|
def _lookup_index(table, columns, **opts)
|
data/lib/delayed/monitor.rb
CHANGED
|
@@ -18,7 +18,7 @@ module Delayed
|
|
|
18
18
|
cattr_accessor :sleep_delay, instance_writer: false, default: 60
|
|
19
19
|
|
|
20
20
|
def initialize
|
|
21
|
-
@jobs = Job.group(
|
|
21
|
+
@jobs = Job.group(:priority, :queue)
|
|
22
22
|
@jobs = @jobs.where(queue: Worker.queues) if Worker.queues.any?
|
|
23
23
|
@memo = {}
|
|
24
24
|
end
|
|
@@ -68,63 +68,72 @@ module Delayed
|
|
|
68
68
|
}
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
def grouped_count(scope)
|
|
72
|
+
Delayed::Job.from(scope.select('priority, queue, COUNT(*) AS count'))
|
|
73
|
+
.group(priority_case_statement, :queue).sum(:count)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def grouped_min(scope, column)
|
|
77
|
+
Delayed::Job.from(scope.select("priority, queue, MIN(#{column}) AS #{column}"))
|
|
78
|
+
.group(priority_case_statement, :queue).minimum(column)
|
|
79
|
+
end
|
|
80
|
+
|
|
71
81
|
def count_grouped
|
|
72
82
|
if Job.connection.supports_partial_index?
|
|
73
|
-
failed_count_grouped.merge(
|
|
83
|
+
failed_count_grouped.merge(live_count_grouped) { |_, l, f| l + f }
|
|
74
84
|
else
|
|
75
|
-
jobs
|
|
85
|
+
grouped_count(jobs)
|
|
76
86
|
end
|
|
77
87
|
end
|
|
78
88
|
|
|
89
|
+
def live_count_grouped
|
|
90
|
+
grouped_count(jobs.live)
|
|
91
|
+
end
|
|
92
|
+
|
|
79
93
|
def future_count_grouped
|
|
80
|
-
jobs.future
|
|
94
|
+
grouped_count(jobs.future)
|
|
81
95
|
end
|
|
82
96
|
|
|
83
97
|
def locked_count_grouped
|
|
84
|
-
@memo[:locked_count_grouped] ||= jobs.claimed
|
|
98
|
+
@memo[:locked_count_grouped] ||= grouped_count(jobs.claimed)
|
|
85
99
|
end
|
|
86
100
|
|
|
87
101
|
def erroring_count_grouped
|
|
88
|
-
jobs.erroring
|
|
102
|
+
grouped_count(jobs.erroring)
|
|
89
103
|
end
|
|
90
104
|
|
|
91
105
|
def failed_count_grouped
|
|
92
|
-
@memo[:failed_count_grouped] ||= jobs.failed
|
|
106
|
+
@memo[:failed_count_grouped] ||= grouped_count(jobs.failed)
|
|
93
107
|
end
|
|
94
108
|
|
|
95
109
|
def max_lock_age_grouped
|
|
96
|
-
oldest_locked_job_grouped.
|
|
97
|
-
metrics[[job.priority.to_i, job.queue]] = Job.db_time_now - job.locked_at
|
|
98
|
-
end
|
|
110
|
+
oldest_locked_job_grouped.transform_values { |locked_at| Job.db_time_now - locked_at }
|
|
99
111
|
end
|
|
100
112
|
|
|
101
113
|
def max_age_grouped
|
|
102
|
-
oldest_workable_job_grouped.
|
|
103
|
-
metrics[[job.priority.to_i, job.queue]] = Job.db_time_now - job.run_at
|
|
104
|
-
end
|
|
114
|
+
oldest_workable_job_grouped.transform_values { |run_at| Job.db_time_now - run_at }
|
|
105
115
|
end
|
|
106
116
|
|
|
107
117
|
def alert_age_percent_grouped
|
|
108
|
-
oldest_workable_job_grouped.each_with_object({}) do |
|
|
109
|
-
max_age = Job.db_time_now -
|
|
110
|
-
|
|
118
|
+
oldest_workable_job_grouped.each_with_object({}) do |((priority, queue), run_at), metrics|
|
|
119
|
+
max_age = Job.db_time_now - run_at
|
|
120
|
+
alert_age = Priority.new(priority).alert_age
|
|
121
|
+
metrics[[priority, queue]] = [max_age / alert_age * 100, 100].min if alert_age
|
|
111
122
|
end
|
|
112
123
|
end
|
|
113
124
|
|
|
114
125
|
def workable_count_grouped
|
|
115
|
-
jobs.claimable
|
|
126
|
+
grouped_count(jobs.claimable)
|
|
116
127
|
end
|
|
117
128
|
|
|
118
129
|
alias working_count_grouped locked_count_grouped
|
|
119
130
|
|
|
120
131
|
def oldest_locked_job_grouped
|
|
121
|
-
jobs.claimed
|
|
122
|
-
.select("#{priority_case_statement} AS priority, queue, MIN(locked_at) AS locked_at")
|
|
132
|
+
grouped_min(jobs.claimed, :locked_at)
|
|
123
133
|
end
|
|
124
134
|
|
|
125
135
|
def oldest_workable_job_grouped
|
|
126
|
-
@memo[:oldest_workable_job_grouped] ||= jobs.claimable
|
|
127
|
-
.select("(#{priority_case_statement}) AS priority, queue, MIN(run_at) AS run_at")
|
|
136
|
+
@memo[:oldest_workable_job_grouped] ||= grouped_min(jobs.claimable, :run_at)
|
|
128
137
|
end
|
|
129
138
|
|
|
130
139
|
def priority_case_statement
|
data/lib/delayed/version.rb
CHANGED