sidekiq-results 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7ec1187a73de7c8ff64f9c71f21e002c45b826ec663dba4f1a95a01c44ff1912
4
+ data.tar.gz: cd5acd9460e127d64948aa0fab090d211f0bcb30817363d0065595391b77f316
5
+ SHA512:
6
+ metadata.gz: f4bdde695f29a1278715ae1cb9f8bcd70bbdbf29a7b0de1a913bd8d593ea281637ca9d315390dd1521669f949ff66413383c4e89bee29490424e1c3f6d3c2239
7
+ data.tar.gz: 9b67f07f80503a4b016f94e44e6f75012a72ce0e3a5f613412ca1e4a709a20523f54df1f41e61bf17705b2739d6f06a39fb8eca132461330cf54af5e72fe25ee
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.5.1
7
+ before_install: gem install bundler -v 1.16.3
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in sidekiq-results.gemspec
6
+ gemspec
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sidekiq-results (0.1.0)
5
+ sidekiq (>= 5.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ connection_pool (2.2.2)
11
+ diff-lcs (1.3)
12
+ rack (2.0.6)
13
+ rack-protection (2.0.5)
14
+ rack
15
+ rake (10.5.0)
16
+ redis (4.1.0)
17
+ rspec (3.8.0)
18
+ rspec-core (~> 3.8.0)
19
+ rspec-expectations (~> 3.8.0)
20
+ rspec-mocks (~> 3.8.0)
21
+ rspec-core (3.8.0)
22
+ rspec-support (~> 3.8.0)
23
+ rspec-expectations (3.8.2)
24
+ diff-lcs (>= 1.2.0, < 2.0)
25
+ rspec-support (~> 3.8.0)
26
+ rspec-mocks (3.8.0)
27
+ diff-lcs (>= 1.2.0, < 2.0)
28
+ rspec-support (~> 3.8.0)
29
+ rspec-support (3.8.0)
30
+ sidekiq (5.2.3)
31
+ connection_pool (~> 2.2, >= 2.2.2)
32
+ rack-protection (>= 1.5.0)
33
+ redis (>= 3.3.5, < 5)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ bundler (~> 1.16)
40
+ rake (~> 10.0)
41
+ rspec (~> 3.0)
42
+ sidekiq-results!
43
+
44
+ BUNDLED WITH
45
+ 1.16.3
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 ichi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+ # Sidekiq::Results
2
+
3
+ Results for sidekiq jobs.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'sidekiq-results'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install sidekiq-results
20
+
21
+ ## Usage
22
+
23
+ Open `Results` tab on your sidekiq web UI.
24
+
25
+ ## TODO
26
+
27
+ - test
28
+
29
+ ## Contributing
30
+
31
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ichi/sidekiq-results.
32
+
33
+ ## License
34
+
35
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "sidekiq/results"
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(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+ require 'sidekiq/web'
2
+ require 'sidekiq/results/version'
3
+ require 'sidekiq/results/result_set'
4
+ require 'sidekiq/results/middleware'
5
+ require 'sidekiq/results/web_extension'
6
+
7
+ module Sidekiq
8
+
9
+ def self.results_max_count=(value)
10
+ @results_max_count = value
11
+ end
12
+
13
+ def self.results_max_count
14
+ return false if @results_max_count === false
15
+ @results_max_count ||= 1000
16
+ end
17
+
18
+ module Results
19
+ LIST_KEY = 'sidekiq:results'
20
+ end
21
+ end
22
+
23
+ Sidekiq.configure_server do |config|
24
+ config.server_middleware do |chain|
25
+ chain.add Sidekiq::Results::Middleware
26
+ end
27
+ end
28
+
29
+ if defined?(Sidekiq::Web)
30
+ Sidekiq::Web.register Sidekiq::Results::WebExtension
31
+ Sidekiq::Web.tabs['Results'] = 'results'
32
+ end
@@ -0,0 +1,6 @@
1
+ en:
2
+ Results: Results
3
+ NoResultsFound: No results found
4
+ StartedAt: Started At
5
+ FinishedAt: Finished At
6
+ Processor: Processor
@@ -0,0 +1,6 @@
1
+ ja:
2
+ Results: 結果
3
+ NoResultsFound: 結果はありません
4
+ StartedAt: 開始日時
5
+ FinishedAt: 完了日時
6
+ Processor: Processor
@@ -0,0 +1,66 @@
1
+ require 'sidekiq/util'
2
+
3
+ module Sidekiq
4
+ module Results
5
+ class Middleware
6
+ include Sidekiq::Util
7
+
8
+ def call(worker, msg, queue)
9
+ data = {
10
+ queue: queue,
11
+ status: 'busy',
12
+ started_at: Time.now.utc.to_f,
13
+ processor: identity,
14
+ }
15
+
16
+ start = msg.merge(data).freeze
17
+ save_result(start)
18
+
19
+ yield
20
+ rescue => e
21
+ data.merge!(
22
+ status: 'failed',
23
+ error_class: e.class.name,
24
+ error_message: e.message,
25
+ error_backtrace: e.backtrace,
26
+ )
27
+
28
+ raise e
29
+ else
30
+ data.merge!(
31
+ status: 'processed',
32
+ )
33
+ ensure
34
+ data.merge!(
35
+ finished_at: Time.now.utc.to_f,
36
+ )
37
+
38
+ finish = msg.merge(data).freeze
39
+ remove_result(start)
40
+ save_result(finish)
41
+ end
42
+
43
+ private
44
+
45
+ def save_result(msg)
46
+ payload = Sidekiq.dump_json(msg)
47
+
48
+ Sidekiq.redis do |conn|
49
+ conn.zadd(LIST_KEY, msg[:started_at], payload)
50
+
51
+ unless Sidekiq.results_max_count == false
52
+ conn.zremrangebyrank(LIST_KEY, 0, -(Sidekiq.results_max_count + 1))
53
+ end
54
+ end
55
+ end
56
+
57
+ def remove_result(msg)
58
+ payload = Sidekiq.dump_json(msg)
59
+
60
+ Sidekiq.redis do |conn|
61
+ conn.zrem(LIST_KEY, payload)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,9 @@
1
+ module Sidekiq
2
+ module Results
3
+ class ResultSet < Sidekiq::JobSet
4
+ def initialize
5
+ super LIST_KEY
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module Sidekiq
2
+ module Results
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,71 @@
1
+ <header class="row">
2
+ <div class="col-sm-5">
3
+ <h3><%= t('Results') %></h3>
4
+ </div>
5
+ <% if @results.size > 0 && @total_size > @count %>
6
+ <div class="col-sm-4">
7
+ <%= erb :_paging, :locals => { :url => "#{root_path}results" } %>
8
+ </div>
9
+ <% end %>
10
+ <%= filtering('results') if respond_to?(:filtering) %>
11
+ </header>
12
+
13
+ <% if @results.size > 0 %>
14
+ <form action="<%= root_path %>results" method="post">
15
+ <%= csrf_tag if respond_to?(:csrf_tag) %>
16
+ <table class="table table-striped table-bordered table-white">
17
+ <thead>
18
+ <tr>
19
+ <th width="20px" class="table-checkbox">
20
+ <label>
21
+ <input type="checkbox" class="check_all" />
22
+ </label>
23
+ </th>
24
+ <th><%= t('Status') %></th>
25
+ <th><%= t('Job') %></th>
26
+ <th><%= t('Arguments') %></th>
27
+ <th><%= t('StartedAt') %></th>
28
+ <th><%= t('FinishedAt') %></th>
29
+ <th><%= t('Time') %></th>
30
+ <th><%= t('Queue') %></th>
31
+ <th><%= t('Processor') %></th>
32
+ <th><%= t('Error') %></th>
33
+ </tr>
34
+ </thead>
35
+ <% @results.each do |entry| %>
36
+ <tr>
37
+ <td class="table-checkbox">
38
+ <label>
39
+ <input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
40
+ </label>
41
+ </td>
42
+ <td><%= status_label(entry['status']) %></td>
43
+ <td><a href="<%= root_path %>results/<%= job_params(entry.item, entry.score) %>"><%= entry.display_class %></a></td>
44
+ <td><%= entry.display_args %></td>
45
+ <td><%= Time.at(entry['started_at']) %></td>
46
+ <td><%= entry['finished_at'] && Time.at(entry['finished_at']) %></td>
47
+ <td><%= entry['finished_at'] && (entry['finished_at'] - entry['started_at']).to_f.round(3) %></td>
48
+ <td><a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a></td>
49
+ <td><%= entry['processor'] %></td>
50
+ <td><%= h entry['error_class'] %></td>
51
+ </tr>
52
+ <% end %>
53
+ </table>
54
+ <input class="btn btn-primary btn-xs pull-left" type="submit" name="retry" value="<%= t('RetryNow') %>" />
55
+ <input class="btn btn-danger btn-xs pull-left" type="submit" name="delete" value="<%= t('Delete') %>" />
56
+ </form>
57
+
58
+ <form action="<%= root_path %>results/all/delete" method="post">
59
+ <%= csrf_tag if respond_to?(:csrf_tag) %>
60
+ <input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
61
+ </form>
62
+
63
+ <% if @results.size > 0 && @total_size > @count %>
64
+ <div class="col-sm-4">
65
+ <%= erb :_paging, :locals => { :url => "#{root_path}results" } %>
66
+ </div>
67
+ <% end %>
68
+
69
+ <% else %>
70
+ <div class="alert alert-success"><%= t('NoResultsFound') %></div>
71
+ <% end %>
@@ -0,0 +1,64 @@
1
+ <%= erb :_job_info, locals: {job: @result, type: @result['retry_count'] ? :retry : nil} %>
2
+
3
+ <header>
4
+ <h3><%= t('Extra') %></h3>
5
+ </header>
6
+ <table class="error table table-bordered table-striped">
7
+ <tbody>
8
+ <tr>
9
+ <th><%= t('Status') %></th>
10
+ <td><%= status_label(@result['status']) %></td>
11
+ </tr>
12
+ <tr>
13
+ <th><%= t('StartedAt') %></th>
14
+ <td><%= Time.at(@result['started_at']) %></td>
15
+ </tr>
16
+ <tr>
17
+ <th><%= t('FinishedAt') %></th>
18
+ <td><%= @result['finished_at'] && Time.at(@result['finished_at']) %></td>
19
+ </tr>
20
+ <tr>
21
+ <th><%= t('Time') %></th>
22
+ <td><%= @result['finished_at'] && (@result['finished_at'] - @result['started_at']).to_f.round(3) %></td>
23
+ </tr>
24
+ <tr>
25
+ <th><%= t('Processor') %></th>
26
+ <td><%= @result['processor'] %></td>
27
+ </tr>
28
+ </tbody>
29
+ </table>
30
+
31
+ <% if @result['error_class'] %>
32
+ <header>
33
+ <h3><%= t('Error') %></h3>
34
+ </header>
35
+ <table class="error table table-bordered table-striped">
36
+ <tbody>
37
+ <tr>
38
+ <th><%= t('ErrorClass') %></th>
39
+ <td>
40
+ <code><%= @result['error_class'] %></code>
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <th><%= t('ErrorMessage') %></th>
45
+ <td><%= @result['error_message'] %></td>
46
+ </tr>
47
+ <% unless @result['error_backtrace'].nil? %>
48
+ <tr>
49
+ <th><%= t('ErrorBacktrace') %></th>
50
+ <td>
51
+ <code><%= @result['error_backtrace'].join("<br/>") %></code>
52
+ </td>
53
+ </tr>
54
+ <% end %>
55
+ </tbody>
56
+ </table>
57
+ <% end %>
58
+
59
+ <form class="form-horizontal" action="<%= root_path %>results/<%= job_params(@result, @result.score) %>" method="post">
60
+ <%= csrf_tag if respond_to?(:csrf_tag) %>
61
+ <a class="btn" href="<%= root_path %>results"><%= t('GoBack') %></a>
62
+ <input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
63
+ <input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
64
+ </form>
@@ -0,0 +1,76 @@
1
+ module Sidekiq
2
+ module Results
3
+ class WebExtension
4
+ def self.registered(app)
5
+ view_path = File.join(File.expand_path("..", __FILE__), "views")
6
+ locale_path = File.expand_path(File.dirname(__FILE__) + '/locales')
7
+
8
+ Sidekiq::Web.settings.locales << locale_path
9
+
10
+ app.helpers do
11
+ def status_label(status)
12
+ labels = {
13
+ 'busy' => '▶',
14
+ 'processed' => '✅',
15
+ 'failed' => '❌',
16
+ }
17
+ labels[status]
18
+ end
19
+ end
20
+
21
+ app.get '/results' do
22
+ @count = (params[:count] || 25).to_i
23
+ (@current_page, @total_size, @results) = page(LIST_KEY, params[:page], @count, reverse: true)
24
+ @results = @results.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
25
+
26
+ render(:erb, File.read(File.join(view_path, 'index.html.erb')))
27
+ end
28
+
29
+ app.post '/results' do
30
+ redirect("#{root_path}results") unless params['key']
31
+
32
+ params['key'].each do |key|
33
+ job = @result = ResultSet.new.fetch(*parse_params(params['key'])).first
34
+ retry_or_delete_or_kill job, params if job
35
+ end
36
+
37
+ redirect_with_query("#{root_path}morgue")
38
+ end
39
+
40
+ app.get '/results/:key' do
41
+ halt 404 unless params['key']
42
+
43
+ @result = ResultSet.new.fetch(*parse_params(params['key'])).first
44
+ redirect("#{root_path}results") unless @result
45
+
46
+ render(:erb, File.read(File.join(view_path, 'show.html.erb')))
47
+ end
48
+
49
+ app.post "/results/:key" do
50
+ halt 404 unless params['key']
51
+
52
+ job = ResultSet.new.fetch(*parse_params(params['key'])).first
53
+ retry_or_delete_or_kill job, params if job
54
+ redirect_with_query("#{root_path}results")
55
+ end
56
+
57
+ app.post "/results/all/delete" do
58
+ ResultSet.new.clear
59
+ redirect "#{root_path}results"
60
+ end
61
+
62
+ app.get '/filter/results' do
63
+ redirect "#{root_path}results"
64
+ end
65
+
66
+ app.post '/filter/results' do
67
+ @results = Sidekiq::Failures::FailureSet.new.scan("*#{params[:substr]}*")
68
+ @current_page = 1
69
+ @count = @total_size = @results.size
70
+
71
+ render(:erb, File.read(File.join(view_path, 'index.html.erb')))
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,31 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "sidekiq/results/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sidekiq-results"
8
+ spec.version = Sidekiq::Results::VERSION
9
+ spec.authors = ["ichi"]
10
+ spec.email = ["ichi.ttht.1@gmail.com"]
11
+
12
+ spec.summary = %q{Results for sidekiq jobs.}
13
+ spec.description = %q{Results for sidekiq jobs.}
14
+ spec.homepage = "https://github.com/ichi/sidekiq-results"
15
+ spec.license = "MIT"
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_dependency "sidekiq", ">= 5.0"
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.16"
29
+ spec.add_development_dependency "rake", "~> 10.0"
30
+ spec.add_development_dependency "rspec", "~> 3.0"
31
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sidekiq-results
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ichi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-12-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sidekiq
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.16'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: Results for sidekiq jobs.
70
+ email:
71
+ - ichi.ttht.1@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/console
84
+ - bin/setup
85
+ - lib/sidekiq/results.rb
86
+ - lib/sidekiq/results/locales/en.yml
87
+ - lib/sidekiq/results/locales/ja.yml
88
+ - lib/sidekiq/results/middleware.rb
89
+ - lib/sidekiq/results/result_set.rb
90
+ - lib/sidekiq/results/version.rb
91
+ - lib/sidekiq/results/views/index.html.erb
92
+ - lib/sidekiq/results/views/show.html.erb
93
+ - lib/sidekiq/results/web_extension.rb
94
+ - sidekiq-results.gemspec
95
+ homepage: https://github.com/ichi/sidekiq-results
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 2.7.6
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: Results for sidekiq jobs.
119
+ test_files: []