active_job_metadata 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 +9 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +128 -0
- data/Rakefile +14 -0
- data/active_job_metadata.gemspec +27 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/active_job_metadata.rb +54 -0
- data/lib/active_job_metadata/all.rb +7 -0
- data/lib/active_job_metadata/lifecycle.rb +19 -0
- data/lib/active_job_metadata/metadata.rb +58 -0
- data/lib/active_job_metadata/timing.rb +44 -0
- data/lib/active_job_metadata/version.rb +3 -0
- metadata +140 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 843028f1e40916f667c6bae2fa228919eb0ed5d3
|
4
|
+
data.tar.gz: 068b6ec80c5f3560a907d3fa609fa4b6408482a5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2fe763b81691b7fa827e4dd41b2a37185a13d65205f4b9a03057d789600780f0925a50f21adf1004afce8b41071c1304c0e60284332e6f817cdeac6c9cc9a416
|
7
|
+
data.tar.gz: 25ef63615d7e34c1b91bca5d5baeb37e792ad729d4ae7a3275f7b29770d680bc84d10a5408c377c05a4a7a0ebe9ea6198eaa2c0393d55878056295f94ef1756e
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
# ActiveJobMetadata
|
2
|
+
|
3
|
+
ActiveJobMetadata lets you store and retrieve metadata associated with ActiveJob jobs regardless of the queue processing library you use.
|
4
|
+
|
5
|
+
Primary use cases include:
|
6
|
+
|
7
|
+
- Providing job status clients
|
8
|
+
- Tracking job performance
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'active_job_metadata'
|
16
|
+
```
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
You can use as much or as little of ActiveJobMetadata as you need.
|
21
|
+
|
22
|
+
Use **Lifecyle** to track the current status of your job:
|
23
|
+
|
24
|
+
class MyJob < ActiveJob::Base
|
25
|
+
include ActiveJobMetadata::Lifecycle
|
26
|
+
|
27
|
+
def perform
|
28
|
+
#...
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
job = MyJob.new
|
33
|
+
job.enque
|
34
|
+
job.status #=> "enqueued"
|
35
|
+
ActiveJobMetadata.find(job.job_id) #=> {status: "enqueued"}
|
36
|
+
|
37
|
+
You can use this in RESTful controllers to let clients query for a job's status:
|
38
|
+
|
39
|
+
class JobsController
|
40
|
+
def create
|
41
|
+
job = MyJob.new
|
42
|
+
job.enque
|
43
|
+
|
44
|
+
render json: {id: job.job_id}
|
45
|
+
end
|
46
|
+
|
47
|
+
def show
|
48
|
+
metadata = ActiveJobMetadata.find(params[:id])
|
49
|
+
|
50
|
+
if metadata
|
51
|
+
render json: metadata
|
52
|
+
else
|
53
|
+
render json: {message: "Not Found"}, status: 404
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Use the **Timing** module to track and report on execution times:
|
59
|
+
|
60
|
+
class TimedJob < ActiveJob::Base
|
61
|
+
include ActiveJobMetadata::Timing
|
62
|
+
after_peform :report_timing
|
63
|
+
|
64
|
+
def perform
|
65
|
+
#...
|
66
|
+
end
|
67
|
+
|
68
|
+
def report_timing
|
69
|
+
Rails.logger.info "Queue Duration: #{queue_duration}"
|
70
|
+
Rails.logger.info "Processing Duration: #{working_duration}"
|
71
|
+
Rails.logger.info "Total Duration: #{total_duration}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
Of course you could hook this up to [statsd](https://github.com/reinh/statsd), or any other place you collect metrics.
|
76
|
+
|
77
|
+
Use the **Metadata** module to track custom information. For instance a long running job might report the percent complete and the name of the last file it processed:
|
78
|
+
|
79
|
+
class LongRunningJob < ActiveJob::Base
|
80
|
+
include ActiveJobMetadata::Metadata
|
81
|
+
metadata :percent_complete, :current_file
|
82
|
+
|
83
|
+
def perform(files)
|
84
|
+
files.each_with_index do |file, i|
|
85
|
+
self.percent_complete = (files.length / i.to_f)
|
86
|
+
self.current_file = file
|
87
|
+
|
88
|
+
IO.open(file) do |io|
|
89
|
+
#...
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
Use this approach to enrich metadata you send back to your client.
|
97
|
+
|
98
|
+
## Configuration
|
99
|
+
|
100
|
+
Although ActiveJobMetadata should mostly work out of the box in a development environment, you will probably want to customize the backing store. ActiveJobMetadata reads and writes to an [ActiveSupport::Cache::Store](http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html). If you use more than one web server, which is likely, you will probably want to use something like [Readthis](https://github.com/sorentwo/readthis) which provides a shared interface via Redis. If you want to use a different backend for ActiveJobMetadata than Rails, create an initializer with your custom store:
|
101
|
+
|
102
|
+
# initializers/active_job_metadata.rb
|
103
|
+
|
104
|
+
# Configure ActiveJobMetadata to use Readthis:
|
105
|
+
ActiveJobMetadata.store = Readthis::Cache.new(
|
106
|
+
expires_in: 2.days.to_i
|
107
|
+
)
|
108
|
+
|
109
|
+
Currently ActiveJobMetadata only uses the `read` and `write` methods, so you can easily store your metadata wherever all your servers can easily access it if you don't mind implementing something that quacks like a [ActiveSupport::Cache::Store](http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html).
|
110
|
+
|
111
|
+
## Alternatives
|
112
|
+
|
113
|
+
It is always wise to consider your alternatives:
|
114
|
+
|
115
|
+
* [active_job_status](https://github.com/cdale77/active_job_status)
|
116
|
+
* [resque-status](https://github.com/quirkey/resque-status) for Resque
|
117
|
+
* [sidekiq-status](https://github.com/utgarda/sidekiq-status) for Sidekiq
|
118
|
+
|
119
|
+
## Development
|
120
|
+
|
121
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
122
|
+
|
123
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
124
|
+
|
125
|
+
## Contributing
|
126
|
+
|
127
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/adamsanderson/active_job_metadata.
|
128
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
|
8
|
+
# Disable warnings to avoid circular load warnings in dependencies
|
9
|
+
t.warning = false
|
10
|
+
|
11
|
+
t.test_files = FileList['test/**/*_test.rb']
|
12
|
+
end
|
13
|
+
|
14
|
+
task :default => :test
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'active_job_metadata/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "active_job_metadata"
|
8
|
+
spec.version = ActiveJobMetadata::VERSION
|
9
|
+
spec.authors = ["adam sanderson"]
|
10
|
+
spec.email = ["netghost@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "Store status and metadata for ActiveJobs"
|
13
|
+
spec.description = "ActiveJobMetadata lets you store and retrieve metadata associated with ActiveJob jobs regardless of the queue processing library you use."
|
14
|
+
spec.homepage = "https://github.com/adamsanderson/active_job_metadata"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "activejob", ">= 4.2", "< 5.1"
|
22
|
+
spec.add_dependency "activesupport", ">= 4.2", "< 5.1"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
25
|
+
spec.add_development_dependency "rake", "~> 11.0"
|
26
|
+
spec.add_development_dependency "minitest", "~> 5.9"
|
27
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "active_job_metadata"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require "active_job_metadata/version"
|
2
|
+
require "active_support"
|
3
|
+
|
4
|
+
module ActiveJobMetadata
|
5
|
+
|
6
|
+
# Prefix used by ActiveJobMetadata for finding and setting metadata
|
7
|
+
# by job id.
|
8
|
+
mattr_accessor(:prefix) do
|
9
|
+
"ActiveJobMetadata"
|
10
|
+
end
|
11
|
+
|
12
|
+
# ActiveSupport::Cache::Store used to save metadata. By default this uses the Rails cache,
|
13
|
+
# though you may want to use a special store if metadata is likely to fall out of the cache.
|
14
|
+
#
|
15
|
+
# Consider adjusting the retention policies to be long enough to last the total lifetime of
|
16
|
+
# a job plus some time afterwards if client code may check it at a later date.
|
17
|
+
mattr_accessor(:store) do
|
18
|
+
Rails.cache if defined? Rails
|
19
|
+
end
|
20
|
+
|
21
|
+
# Same as find, but will raise an ActiveJobMetadata::MetadataNotFound exception if
|
22
|
+
# the job's metadata is not found.
|
23
|
+
def self.find!(job_id)
|
24
|
+
find(job_id) || raise(MetadataNotFound.new("Could not find metadata: #{job_id.inspect}"))
|
25
|
+
end
|
26
|
+
|
27
|
+
# Finds a job's metadata, otherwise returns nil. Note that depending on how your store is
|
28
|
+
# configured, metadata may not always be available. For instance, if your store is configured
|
29
|
+
# to expire data after one day, then that metadata will no longer be available.
|
30
|
+
def self.find(job_id)
|
31
|
+
metadata_key = self.key(job_id)
|
32
|
+
store.read(metadata_key)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Writes metadata for a job directly to the cache. Typically you should use accessors defined
|
36
|
+
# via `metadata` on a class. See ActiveJobMetadata::Metdadata for more information.
|
37
|
+
def self.write(job_id, metadata)
|
38
|
+
metadata_key = self.key(job_id)
|
39
|
+
store.write(metadata_key, metadata)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Generates a key for a given job id. You generally shouldn't need this.
|
43
|
+
def self.key(job_id)
|
44
|
+
"#{ActiveJobMetadata.prefix}-#{job_id}"
|
45
|
+
end
|
46
|
+
|
47
|
+
class MetadataNotFound < StandardError
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
require "active_job_metadata/metadata"
|
52
|
+
require "active_job_metadata/lifecycle"
|
53
|
+
require "active_job_metadata/timing"
|
54
|
+
require "active_job_metadata/all"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Use Lifecyle to track the current status of your job.
|
2
|
+
#
|
3
|
+
module ActiveJobMetadata::Lifecycle
|
4
|
+
ENQUEUED = "enqueued"
|
5
|
+
RUNNING = "running"
|
6
|
+
DONE = "done"
|
7
|
+
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
include ActiveJobMetadata::Metadata
|
10
|
+
|
11
|
+
included do
|
12
|
+
metadata :status
|
13
|
+
|
14
|
+
after_enqueue { self.status = "enqueued" }
|
15
|
+
before_perform { self.status = "running" }
|
16
|
+
after_perform { self.status = "done" }
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Use Metadata to define custom metadata for your job.
|
2
|
+
#
|
3
|
+
module ActiveJobMetadata::Metadata
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
# No-op
|
8
|
+
end
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
|
12
|
+
# Defines metadata accessors for each specified attribute.
|
13
|
+
#
|
14
|
+
# class LongRunningJob < ActiveJob::Base
|
15
|
+
# include ActiveJobMetadata::Metadata
|
16
|
+
# metadata :percent_complete, :current_file
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# job = LongRunningJob.new
|
20
|
+
# job.percent_complete = 80
|
21
|
+
# job.metadata #=> {percent_complete: 80}
|
22
|
+
#
|
23
|
+
def metadata *names
|
24
|
+
names.each do |name|
|
25
|
+
|
26
|
+
define_method(name) do
|
27
|
+
self.metadata[name.to_sym]
|
28
|
+
end
|
29
|
+
|
30
|
+
define_method("#{name}=") do |value|
|
31
|
+
self.metadata[name.to_sym] = value
|
32
|
+
save_metadata
|
33
|
+
value
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns all metadata for the current job.
|
41
|
+
def metadata
|
42
|
+
@metadata ||= ActiveJobMetadata.find(job_id) || {}
|
43
|
+
end
|
44
|
+
|
45
|
+
# Merges data into the current job's metdata.
|
46
|
+
def metadata= hash
|
47
|
+
metadata.merge!(hash)
|
48
|
+
save_metadata
|
49
|
+
end
|
50
|
+
|
51
|
+
# Writes metadata to `ActiveJobMetadata.store`
|
52
|
+
def save_metadata
|
53
|
+
ActiveJobMetadata.write(job_id, metadata)
|
54
|
+
|
55
|
+
metadata
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Use Timing to track and report on execution times.
|
2
|
+
#
|
3
|
+
module ActiveJobMetadata::Timing
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include ActiveJobMetadata::Metadata
|
6
|
+
|
7
|
+
included do
|
8
|
+
metadata :enqueued_at
|
9
|
+
metadata :started_at
|
10
|
+
metadata :done_at
|
11
|
+
|
12
|
+
after_enqueue { self.enqueued_at = Time.now }
|
13
|
+
before_perform { self.started_at = Time.now }
|
14
|
+
after_perform { self.done_at = Time.now }
|
15
|
+
end
|
16
|
+
|
17
|
+
# The queue duration is the time in seconds a job spent in the queue before
|
18
|
+
# it was processed. If it has not been enqueued or processing
|
19
|
+
# has not yet begun, it will return nil.
|
20
|
+
def queue_duration
|
21
|
+
return nil unless enqueued_at && started_at
|
22
|
+
started_at - enqueued_at
|
23
|
+
end
|
24
|
+
|
25
|
+
# The working duration is the time in seconds a job spent in the process
|
26
|
+
# method. If process has not yet been called, or process has not finished
|
27
|
+
# it will return nil.
|
28
|
+
def working_duration
|
29
|
+
return nil unless done_at && started_at
|
30
|
+
done_at - started_at
|
31
|
+
end
|
32
|
+
|
33
|
+
# The total duration is the sum of the queue and working duration. This
|
34
|
+
# gives a measure of how long it took from enqueuing the job to completing
|
35
|
+
# all processing.
|
36
|
+
def total_duration
|
37
|
+
q = queue_duration
|
38
|
+
w = working_duration
|
39
|
+
return nil unless q && w
|
40
|
+
|
41
|
+
queue_duration + working_duration
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_job_metadata
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- adam sanderson
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activejob
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.2'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.1'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.2'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.1'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: activesupport
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '4.2'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '5.1'
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '4.2'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '5.1'
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: bundler
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '1.10'
|
60
|
+
type: :development
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - "~>"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '1.10'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: rake
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '11.0'
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '11.0'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: minitest
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '5.9'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '5.9'
|
95
|
+
description: ActiveJobMetadata lets you store and retrieve metadata associated with
|
96
|
+
ActiveJob jobs regardless of the queue processing library you use.
|
97
|
+
email:
|
98
|
+
- netghost@gmail.com
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- ".gitignore"
|
104
|
+
- ".travis.yml"
|
105
|
+
- Gemfile
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- active_job_metadata.gemspec
|
109
|
+
- bin/console
|
110
|
+
- bin/setup
|
111
|
+
- lib/active_job_metadata.rb
|
112
|
+
- lib/active_job_metadata/all.rb
|
113
|
+
- lib/active_job_metadata/lifecycle.rb
|
114
|
+
- lib/active_job_metadata/metadata.rb
|
115
|
+
- lib/active_job_metadata/timing.rb
|
116
|
+
- lib/active_job_metadata/version.rb
|
117
|
+
homepage: https://github.com/adamsanderson/active_job_metadata
|
118
|
+
licenses: []
|
119
|
+
metadata: {}
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 2.4.5.1
|
137
|
+
signing_key:
|
138
|
+
specification_version: 4
|
139
|
+
summary: Store status and metadata for ActiveJobs
|
140
|
+
test_files: []
|