yabeda-delayed_job 0.1.0
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 +7 -0
- data/.gitignore +56 -0
- data/.rspec +3 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +11 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +92 -0
- data/LICENSE +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +69 -0
- data/Rakefile +11 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/docker-compose.yml +34 -0
- data/docs/yabeda-delayed_job-grafana.png +0 -0
- data/example/Gemfile +12 -0
- data/example/Gemfile.lock +62 -0
- data/example/delayed_job.rb +23 -0
- data/example/docker-compose.yml +72 -0
- data/example/enqueuer.rb +27 -0
- data/example/grafana/dashboards/delayed_job.json +618 -0
- data/example/grafana/grafana.ini +9 -0
- data/example/grafana/provisioning/dashboards/delayed_job.yml +0 -0
- data/example/grafana/provisioning/datasources/prometheus.yml +8 -0
- data/example/jobs.rb +13 -0
- data/example/log/delayed_job.log +12 -0
- data/example/prometheus/config.yml +19 -0
- data/example/prometheus_store.rb +8 -0
- data/lib/yabeda/delayed_job.rb +102 -0
- data/lib/yabeda/delayed_job/plugin.rb +43 -0
- data/lib/yabeda/delayed_job/version.rb +7 -0
- data/yabeda-delayed_job.gemspec +37 -0
- metadata +161 -0
|
File without changes
|
data/example/jobs.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Logfile created on 2021-06-21 18:52:52 +0000 by logger.rb/v1.4.3
|
|
2
|
+
I, [2021-06-21T18:52:52.998760 #85] INFO -- : 2021-06-21T18:52:52+0000: [Worker(delayed_job host:d7008330188a pid:85)] Starting job worker
|
|
3
|
+
I, [2021-06-21T18:52:53.031345 #85] INFO -- : 2021-06-21T18:52:53+0000: [Worker(delayed_job host:d7008330188a pid:85)] Job RandomJob#call (id=1) RUNNING
|
|
4
|
+
I, [2021-06-21T18:52:55.246040 #85] INFO -- : 2021-06-21T18:52:55+0000: [Worker(delayed_job host:d7008330188a pid:85)] Job RandomJob#call (id=1) COMPLETED after 2.2140
|
|
5
|
+
I, [2021-06-21T18:52:55.249806 #85] INFO -- : 2021-06-21T18:52:55+0000: [Worker(delayed_job host:d7008330188a pid:85)] Job RandomJob#call (id=2) RUNNING
|
|
6
|
+
I, [2021-06-21T18:52:59.055058 #85] INFO -- : 2021-06-21T18:52:59+0000: [Worker(delayed_job host:d7008330188a pid:85)] Job RandomJob#call (id=2) COMPLETED after 3.8045
|
|
7
|
+
I, [2021-06-21T18:52:59.058246 #85] INFO -- : 2021-06-21T18:52:59+0000: [Worker(delayed_job host:d7008330188a pid:85)] Job RandomJob#call (id=3) RUNNING
|
|
8
|
+
I, [2021-06-21T18:52:59.909979 #85] INFO -- : 2021-06-21T18:52:59+0000: [Worker(delayed_job host:d7008330188a pid:85)] Job RandomJob#call (id=3) COMPLETED after 0.8510
|
|
9
|
+
I, [2021-06-21T18:52:59.914425 #85] INFO -- : 2021-06-21T18:52:59+0000: [Worker(delayed_job host:d7008330188a pid:85)] Job RandomJob#call (id=4) RUNNING
|
|
10
|
+
I, [2021-06-21T18:53:00.916535 #85] INFO -- : 2021-06-21T18:53:00+0000: [Worker(delayed_job host:d7008330188a pid:85)] Exiting...
|
|
11
|
+
I, [2021-06-21T18:53:04.921236 #85] INFO -- : 2021-06-21T18:53:04+0000: [Worker(delayed_job host:d7008330188a pid:85)] Job RandomJob#call (id=4) COMPLETED after 5.0059
|
|
12
|
+
I, [2021-06-21T18:53:04.922786 #85] INFO -- : 2021-06-21T18:53:04+0000: [Worker(delayed_job host:d7008330188a pid:85)] 4 jobs processed at 0.3355 j/s, 0 failed
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
global:
|
|
2
|
+
scrape_interval: 5s
|
|
3
|
+
scrape_timeout: 5s
|
|
4
|
+
evaluation_interval: 5s
|
|
5
|
+
|
|
6
|
+
scrape_configs:
|
|
7
|
+
- job_name: 'enqueuer'
|
|
8
|
+
scheme: http
|
|
9
|
+
metrics_path: '/metrics'
|
|
10
|
+
static_configs:
|
|
11
|
+
- targets:
|
|
12
|
+
- 'enqueuer:9394'
|
|
13
|
+
- job_name: 'delayed_job'
|
|
14
|
+
scheme: http
|
|
15
|
+
metrics_path: '/metrics'
|
|
16
|
+
static_configs:
|
|
17
|
+
- targets:
|
|
18
|
+
- 'delayed_job:9394'
|
|
19
|
+
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'yabeda/delayed_job/version'
|
|
4
|
+
require 'delayed_job'
|
|
5
|
+
require 'yabeda'
|
|
6
|
+
require 'yabeda/delayed_job/plugin'
|
|
7
|
+
|
|
8
|
+
module Yabeda
|
|
9
|
+
module DelayedJob
|
|
10
|
+
class Error < StandardError; end
|
|
11
|
+
|
|
12
|
+
LONG_RUNNING_JOB_RUNTIME_BUCKETS = [
|
|
13
|
+
0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, # standard (from Prometheus)
|
|
14
|
+
30, 60, 120, 300, 1800, 3600, 21_600 # DelayedJob tasks may be very long-running
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
17
|
+
::Yabeda.configure do
|
|
18
|
+
group :delayed_job
|
|
19
|
+
|
|
20
|
+
counter :jobs_enqueued_total, tags: %i[queue worker], comment: 'A counter of the total number of jobs enqueued.'
|
|
21
|
+
counter :jobs_failed_total, tags: %i[queue worker error], comment: 'asdf'
|
|
22
|
+
counter :jobs_errored_total, tags: %i[queue worker error], comment: 'asdf'
|
|
23
|
+
|
|
24
|
+
histogram :job_runtime, comment: 'A histogram of the job execution time.',
|
|
25
|
+
unit: :seconds, per: :job,
|
|
26
|
+
tags: %i[queue worker],
|
|
27
|
+
buckets: LONG_RUNNING_JOB_RUNTIME_BUCKETS
|
|
28
|
+
gauge :running_job_runtime, tags: %i[queue worker], aggregation: :max, unit: :seconds,
|
|
29
|
+
comment: 'How long currently running jobs are running ' \
|
|
30
|
+
'(useful for detection of hung jobs)'
|
|
31
|
+
gauge :jobs_waiting_count, tags: %i[queue], comment: 'The number of jobs waiting to process in sidekiq.'
|
|
32
|
+
gauge :queue_latency, tags: %i[queue],
|
|
33
|
+
comment: 'The queue latency, the difference in seconds since the oldest ' \
|
|
34
|
+
'job in the queue was enqueued'
|
|
35
|
+
|
|
36
|
+
collect do
|
|
37
|
+
if ::Yabeda::DelayedJob.server?
|
|
38
|
+
Yabeda::DelayedJob.track_max_job_runtime
|
|
39
|
+
::Yabeda::DelayedJob.track_database_metrics if ::Yabeda::DelayedJob.active_record_adapter?
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class << self
|
|
45
|
+
def server?
|
|
46
|
+
require 'delayed/command'
|
|
47
|
+
@server ||= ObjectSpace.each_object(Delayed::Command).any?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def labelize(job)
|
|
51
|
+
result = { queue: job.queue, worker: job.name }
|
|
52
|
+
result.merge!(error: job.error.class.name) if job.error
|
|
53
|
+
result
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def track_database_metrics
|
|
57
|
+
job_scope.select(:queue).count.each do |queue, count|
|
|
58
|
+
Yabeda.delayed_job.jobs_waiting_count.set({ queue: queue }, count)
|
|
59
|
+
end
|
|
60
|
+
job_scope.select('queue, max(NOW() - run_at) latency').each do |job|
|
|
61
|
+
Yabeda.delayed_job.queue_latency.set({ queue: job.queue }, job.latency)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def job_scope
|
|
66
|
+
db_time_now = ::Delayed::Worker.backend.db_time_now
|
|
67
|
+
::Delayed::Worker.backend.where(
|
|
68
|
+
'(run_at <= ? AND (locked_at IS NULL OR locked_at < ?)) AND failed_at IS NULL',
|
|
69
|
+
db_time_now,
|
|
70
|
+
db_time_now - ::Delayed::Worker.max_run_time
|
|
71
|
+
).group(:queue)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def active_record_adapter?
|
|
75
|
+
defined?(Delayed::Backend::ActiveRecord::Job) &&
|
|
76
|
+
Delayed::Worker.backend.name == Delayed::Backend::ActiveRecord::Job.name
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Hash of hashes containing all currently running jobs' start timestamps
|
|
80
|
+
# to calculate maximum durations of currently running not yet completed jobs
|
|
81
|
+
# { { queue: "default", worker: "SomeJob" } => { "jid1" => 100500, "jid2" => 424242 } }
|
|
82
|
+
attr_accessor :jobs_started_at
|
|
83
|
+
|
|
84
|
+
def track_max_job_runtime
|
|
85
|
+
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
86
|
+
::Yabeda::DelayedJob.jobs_started_at.each do |labels, jobs|
|
|
87
|
+
oldest_job_started_at = jobs.values.min
|
|
88
|
+
oldest_job_duration = oldest_job_started_at ? (now - oldest_job_started_at).round(3) : 0
|
|
89
|
+
Yabeda.delayed_job.running_job_runtime.set(labels, oldest_job_duration)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def elapsed(start)
|
|
94
|
+
(Process.clock_gettime(Process::CLOCK_MONOTONIC) - start).round(3)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
self.jobs_started_at = Concurrent::Hash.new { |hash, key| hash[key] = Concurrent::Hash.new }
|
|
99
|
+
|
|
100
|
+
Delayed::Worker.plugins << ::Yabeda::DelayedJob::Plugin
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'benchmark'
|
|
4
|
+
|
|
5
|
+
module Yabeda
|
|
6
|
+
module DelayedJob
|
|
7
|
+
class Plugin < ::Delayed::Plugin
|
|
8
|
+
callbacks do |lifecycle|
|
|
9
|
+
lifecycle.after(:enqueue) do |job|
|
|
10
|
+
labels = ::Yabeda::DelayedJob.labelize(job)
|
|
11
|
+
::Yabeda.delayed_job.jobs_enqueued_total.increment(labels)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
lifecycle.after(:failure) do |_worker, job|
|
|
15
|
+
labels = ::Yabeda::DelayedJob.labelize(job)
|
|
16
|
+
::Yabeda.delayed_job.jobs_failed_total.increment(labels)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
lifecycle.after(:error) do |_worker, job|
|
|
20
|
+
labels = ::Yabeda::DelayedJob.labelize(job)
|
|
21
|
+
::Yabeda.delayed_job.jobs_errored_total.increment(labels)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
lifecycle.around(:perform) do |worker, job, &block|
|
|
25
|
+
labels = ::Yabeda::DelayedJob.labelize(job)
|
|
26
|
+
|
|
27
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC).tap do |start|
|
|
28
|
+
Yabeda::DelayedJob.jobs_started_at[labels][job.id] = start
|
|
29
|
+
|
|
30
|
+
block.call(worker)
|
|
31
|
+
|
|
32
|
+
Yabeda.delayed_job.job_runtime.measure(
|
|
33
|
+
labels,
|
|
34
|
+
::Yabeda::DelayedJob.elapsed(start)
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
ensure
|
|
38
|
+
Yabeda::DelayedJob.jobs_started_at[labels].delete(job.id)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
+
require 'yabeda/delayed_job/version'
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |spec|
|
|
8
|
+
spec.name = 'yabeda-delayed_job'
|
|
9
|
+
spec.version = Yabeda::DelayedJob::VERSION
|
|
10
|
+
spec.authors = ['Dmitry']
|
|
11
|
+
spec.email = ['dsalahutdinov@gmail.com']
|
|
12
|
+
|
|
13
|
+
spec.summary = 'Monitoring for delayed_job background worker'
|
|
14
|
+
spec.description = 'Extends Yabeda to colleck delayed_job metrics'
|
|
15
|
+
spec.homepage = 'https://github.com/yabeda-rb/yabeda-delayed_job'
|
|
16
|
+
spec.license = 'MIT'
|
|
17
|
+
|
|
18
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
19
|
+
spec.metadata['source_code_uri'] = 'https://github.com/yabeda-rb/yabeda-delayed_job'
|
|
20
|
+
|
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
25
|
+
end
|
|
26
|
+
spec.bindir = 'exe'
|
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
28
|
+
spec.require_paths = ['lib']
|
|
29
|
+
|
|
30
|
+
spec.add_dependency 'delayed_job'
|
|
31
|
+
spec.add_dependency 'yabeda'
|
|
32
|
+
|
|
33
|
+
spec.add_development_dependency 'bundler'
|
|
34
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
35
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
36
|
+
spec.add_development_dependency 'rubocop', '~> 1.15'
|
|
37
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: yabeda-delayed_job
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Dmitry
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2021-07-01 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: delayed_job
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: yabeda
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: bundler
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rake
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '10.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '10.0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rspec
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '3.0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '3.0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rubocop
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '1.15'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '1.15'
|
|
97
|
+
description: Extends Yabeda to colleck delayed_job metrics
|
|
98
|
+
email:
|
|
99
|
+
- dsalahutdinov@gmail.com
|
|
100
|
+
executables: []
|
|
101
|
+
extensions: []
|
|
102
|
+
extra_rdoc_files: []
|
|
103
|
+
files:
|
|
104
|
+
- ".gitignore"
|
|
105
|
+
- ".rspec"
|
|
106
|
+
- ".rubocop.yml"
|
|
107
|
+
- ".travis.yml"
|
|
108
|
+
- CODE_OF_CONDUCT.md
|
|
109
|
+
- Gemfile
|
|
110
|
+
- Gemfile.lock
|
|
111
|
+
- LICENSE
|
|
112
|
+
- LICENSE.txt
|
|
113
|
+
- README.md
|
|
114
|
+
- Rakefile
|
|
115
|
+
- bin/console
|
|
116
|
+
- bin/setup
|
|
117
|
+
- docker-compose.yml
|
|
118
|
+
- docs/yabeda-delayed_job-grafana.png
|
|
119
|
+
- example/Gemfile
|
|
120
|
+
- example/Gemfile.lock
|
|
121
|
+
- example/delayed_job.rb
|
|
122
|
+
- example/docker-compose.yml
|
|
123
|
+
- example/enqueuer.rb
|
|
124
|
+
- example/grafana/dashboards/delayed_job.json
|
|
125
|
+
- example/grafana/grafana.ini
|
|
126
|
+
- example/grafana/provisioning/dashboards/delayed_job.yml
|
|
127
|
+
- example/grafana/provisioning/datasources/prometheus.yml
|
|
128
|
+
- example/jobs.rb
|
|
129
|
+
- example/log/delayed_job.log
|
|
130
|
+
- example/prometheus/config.yml
|
|
131
|
+
- example/prometheus_store.rb
|
|
132
|
+
- lib/yabeda/delayed_job.rb
|
|
133
|
+
- lib/yabeda/delayed_job/plugin.rb
|
|
134
|
+
- lib/yabeda/delayed_job/version.rb
|
|
135
|
+
- yabeda-delayed_job.gemspec
|
|
136
|
+
homepage: https://github.com/yabeda-rb/yabeda-delayed_job
|
|
137
|
+
licenses:
|
|
138
|
+
- MIT
|
|
139
|
+
metadata:
|
|
140
|
+
homepage_uri: https://github.com/yabeda-rb/yabeda-delayed_job
|
|
141
|
+
source_code_uri: https://github.com/yabeda-rb/yabeda-delayed_job
|
|
142
|
+
post_install_message:
|
|
143
|
+
rdoc_options: []
|
|
144
|
+
require_paths:
|
|
145
|
+
- lib
|
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - ">="
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '0'
|
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
|
+
requirements:
|
|
153
|
+
- - ">="
|
|
154
|
+
- !ruby/object:Gem::Version
|
|
155
|
+
version: '0'
|
|
156
|
+
requirements: []
|
|
157
|
+
rubygems_version: 3.2.15
|
|
158
|
+
signing_key:
|
|
159
|
+
specification_version: 4
|
|
160
|
+
summary: Monitoring for delayed_job background worker
|
|
161
|
+
test_files: []
|