sidekiq-undertaker 1.1.1 → 1.4.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 +4 -4
- data/.github/workflows/ruby-build.yml +31 -3
- data/.rubocop.yml +4 -0
- data/.rubocop_codeclimate.yml +9 -0
- data/CHANGELOG.md +19 -0
- data/README.md +8 -6
- data/assets/Undertaker_demo_1_job_1_error.png +0 -0
- data/assets/Undertaker_demo_1_job_all_errors.png +0 -0
- data/assets/Undertaker_demo_all_errors.png +0 -0
- data/assets/Undertaker_demo_all_jobs.png +0 -0
- data/assets/Undertaker_demo_all_jobs_1_error.png +0 -0
- data/lib/sidekiq/undertaker/dead_job.rb +10 -2
- data/lib/sidekiq/undertaker/job_distributor.rb +4 -0
- data/lib/sidekiq/undertaker/job_filter.rb +7 -2
- data/lib/sidekiq/undertaker/version.rb +1 -1
- data/lib/sidekiq/undertaker/web_extension/api_helpers.rb +104 -26
- data/lib/sidekiq/undertaker/web_extension.rb +17 -8
- data/sidekiq-undertaker.gemspec +6 -5
- data/spec/fixtures/approvals/sidekiq_undertaker_webextension/show_filter/when_filter_page_is_called/behaves_like_a_page/the_displayed_page_is_correct_for_sidekiqv6.approved.txt +32 -18
- data/spec/fixtures/approvals/sidekiq_undertaker_webextension/show_filter/when_job_classbucket_page_is_called/behaves_like_a_page/the_displayed_page_is_correct_for_sidekiqv6.approved.txt +37 -39
- data/spec/fixtures/approvals/sidekiq_undertaker_webextension/show_filter/when_job_classbucket_page_is_polled/behaves_like_a_page/the_displayed_page_is_correct_for_sidekiqv6.approved.txt +37 -39
- data/spec/fixtures/approvals/sidekiq_undertaker_webextension/show_filter/when_job_classerror_classbucket_page_is_called/behaves_like_a_page/the_displayed_page_is_correct_for_sidekiqv6.approved.txt +231 -0
- data/spec/fixtures/approvals/sidekiq_undertaker_webextension/show_filter/when_job_classerror_classbucket_page_is_polled/behaves_like_a_page/the_displayed_page_is_correct_for_sidekiqv6.approved.txt +231 -0
- data/spec/fixtures/approvals/sidekiq_undertaker_webextension/show_morgue/when_job_classerrorbucket_is_called/with_all_failures_and_errors/behaves_like_a_page/the_displayed_page_is_correct_for_sidekiqv6.approved.txt +26 -21
- data/spec/fixtures/approvals/sidekiq_undertaker_webextension/show_morgue/when_job_classerrorbucket_is_called/with_job_class_error_and_specific_error_message/behaves_like_a_page/the_displayed_page_is_correct_for_sidekiqv6.approved.txt +284 -0
- data/spec/fixtures/approvals/sidekiq_undertaker_webextension/show_morgue/when_job_classerrorbucket_is_called/with_job_class_error_and_specific_error_message/with_pagination/behaves_like_a_page/the_displayed_page_is_correct_for_sidekiqv6.approved.txt +1310 -0
- data/spec/fixtures/approvals/sidekiq_undertaker_webextension/show_morgue/when_job_classerrorbucket_is_called/with_specific_job_class_and_a_specific_error/behaves_like_a_page/the_displayed_page_is_correct_for_sidekiqv6.approved.txt +24 -19
- data/spec/fixtures/approvals/sidekiq_undertaker_webextension/show_morgue/when_job_classerrorbucket_is_called/with_specific_job_class_and_a_specific_error/with_pagination/behaves_like_a_page/the_displayed_page_is_correct_for_sidekiqv6.approved.txt +72 -67
- data/spec/sidekiq/undertaker/dead_jobs_spec.rb +7 -4
- data/spec/sidekiq/undertaker/job_distributor_spec.rb +41 -19
- data/spec/sidekiq/undertaker/job_filter_spec.rb +26 -9
- data/spec/sidekiq/undertaker/web_extension_spec.rb +172 -14
- data/spec/spec_helper.rb +4 -0
- data/web/locales/en.yml +2 -0
- data/web/views/filter.erb +17 -1
- data/web/views/filter_job_class.erb +8 -8
- data/web/views/filter_job_class_error_class.erb +36 -0
- data/web/views/morgue.erb +9 -2
- metadata +38 -30
- data/.travis.yml +0 -51
- data/Demo_Filter.png +0 -0
- data/Demo_Job_Filter.png +0 -0
- data/Demo_Morgue_1_Job.png +0 -0
- data/Demo_Morgue_all.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9faade9f819fcaff3bc2246d68197d085f6f90b10b82f38290f5a3cc5752f07
|
4
|
+
data.tar.gz: c08b3349474057a180eecf4cc64b0bb15f43112b264833bc6f9441b5ee139549
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d5e1d644890b7ef70348f41faf14961852f76f41dbd3ee9f3fd85a57fc29ee97a3476e2bf224a41f6e76ec17219e7e7ac04abcd6f569fee956883c0b72ad786
|
7
|
+
data.tar.gz: df1f8590c18238ed71a20d380510375f0eba41ea07e2cfd49d4f1e2f3bd0d2d8f3aad43b0bb07fcea9d44dbd242ef0551e93bc3b5091d470d39d3e12e86b0fcf
|
@@ -34,12 +34,15 @@ jobs:
|
|
34
34
|
- '2.7'
|
35
35
|
- 'jruby'
|
36
36
|
- 'jruby-9.3.2.0'
|
37
|
-
- 'jruby-9.2.20.
|
37
|
+
- 'jruby-9.2.20.1'
|
38
38
|
- 'truffleruby'
|
39
39
|
- 'truffleruby+graalvm'
|
40
40
|
|
41
|
+
env:
|
42
|
+
JRUBY_OPTS: '--debug'
|
43
|
+
|
41
44
|
steps:
|
42
|
-
- uses: actions/checkout@
|
45
|
+
- uses: actions/checkout@v3
|
43
46
|
- name: Set up Ruby
|
44
47
|
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
45
48
|
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
@@ -48,4 +51,29 @@ jobs:
|
|
48
51
|
ruby-version: ${{ matrix.ruby-version }}
|
49
52
|
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
50
53
|
- name: Run tests
|
51
|
-
run: bundle exec rspec
|
54
|
+
run: COVERAGE=true bundle exec rspec
|
55
|
+
- name: 'Upload Coverage Report'
|
56
|
+
uses: actions/upload-artifact@v3
|
57
|
+
if: ${{ matrix.ruby-version == 'ruby' }}
|
58
|
+
with:
|
59
|
+
name: coverage-report
|
60
|
+
path: ./coverage
|
61
|
+
retention-days: 1
|
62
|
+
|
63
|
+
coverage:
|
64
|
+
needs: [ test ]
|
65
|
+
name: coverage
|
66
|
+
runs-on: ubuntu-latest
|
67
|
+
steps:
|
68
|
+
- uses: actions/checkout@v3
|
69
|
+
- name: Download Coverage Report
|
70
|
+
uses: actions/download-artifact@v3
|
71
|
+
with:
|
72
|
+
name: coverage-report
|
73
|
+
path: ./coverage
|
74
|
+
- uses: paambaati/codeclimate-action@v3.0.0
|
75
|
+
env:
|
76
|
+
# Set CC_TEST_REPORTER_ID as secret of your repo
|
77
|
+
CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}}
|
78
|
+
with:
|
79
|
+
debug: true
|
data/.rubocop.yml
CHANGED
data/.rubocop_codeclimate.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,25 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## [1.4.0] - 2022-06-03
|
6
|
+
### Added
|
7
|
+
- Added a filter based on error messages
|
8
|
+
|
9
|
+
### Changed
|
10
|
+
- Updated rubocop to version 1.30
|
11
|
+
- Updated rubyzip to version 2.3
|
12
|
+
|
13
|
+
### Removed
|
14
|
+
- Removed Travis CI integration
|
15
|
+
|
16
|
+
## [1.3.0] - 2022-04-27
|
17
|
+
### Added
|
18
|
+
- Added option to export and re-import dead jobs
|
19
|
+
|
20
|
+
## [1.2.0] - 2022-02-03
|
21
|
+
### Changed
|
22
|
+
- Updated sidekiq dependency to 6.4.0
|
23
|
+
|
5
24
|
## [1.1.1] - 2022-02-03
|
6
25
|
### Added
|
7
26
|
- Added CHANGELOG.md
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Sidekiq::Undertaker
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/sidekiq-undertaker)
|
4
|
-
[](https://github.com/ThomasKoppensteiner/sidekiq-undertaker/actions/workflows/ruby-build.yml)
|
5
5
|
[](https://codeclimate.com/github/ThomasKoppensteiner/sidekiq-undertaker)
|
6
6
|
[](https://codeclimate.com/github/ThomasKoppensteiner/sidekiq-undertaker/test_coverage)
|
7
7
|
[](https://github.com/rubocop-hq/rubocop)
|
@@ -45,24 +45,24 @@ Or install it yourself as:
|
|
45
45
|
|
46
46
|
The filter page shows a table with time-buckets as columns and rows for each job class.
|
47
47
|
|
48
|
-

|
49
49
|
|
50
50
|
#### Job Filter View
|
51
51
|
|
52
52
|
For each job class, you can drill down to view error distribution based on
|
53
53
|
error class.
|
54
54
|
|
55
|
-

|
56
56
|
|
57
57
|
#### Morgue View
|
58
58
|
Finally, click on the individual error counts to display details of the
|
59
59
|
errors in a list form.
|
60
60
|
|
61
|
-

|
62
62
|
|
63
63
|
The morgue view can, for example, also show an error distribution over all job classes.
|
64
64
|
|
65
|
-

|
66
66
|
|
67
67
|
## Contributing
|
68
68
|
|
@@ -81,7 +81,9 @@ this fork was renamed to `sidekiq-undertaker`.
|
|
81
81
|
|
82
82
|
The [Sidekiq-Cleaner](https://github.com/HackingHabits/sidekiq-cleaner) gem was originally created by [Madan Thangavelu](https://github.com/HackingHabits).
|
83
83
|
[Tout](https://github.com/Tout/sidekiq-cleaner) and [TheWudu](https://github.com/TheWudu/sidekiq-cleaner) also contributed to it.
|
84
|
-
|
84
|
+
[Zlatko Rednjak](https://github.com/Rednjak) added the initial version of the `CHANGELOG.md`.
|
85
|
+
[Lucas Dell'Isola](https://github.com/ldellisola) added the export/import feature for dead jobs.
|
86
|
+
[thoesl](https://github.com/thoesl) added the error message based filter.
|
85
87
|
|
86
88
|
For the complete list of network members have a look at the [fork overview](https://github.com/ThomasKoppensteiner/sidekiq-undertaker/network/members).
|
87
89
|
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -27,7 +27,7 @@ module Sidekiq
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
attr_reader :job_class, :time_elapsed_since_failure, :error_class, :bucket_name, :job
|
30
|
+
attr_reader :job_class, :time_elapsed_since_failure, :error_class, :error_msg, :bucket_name, :job
|
31
31
|
|
32
32
|
def initialize(args)
|
33
33
|
@job = args.fetch(:job)
|
@@ -35,12 +35,14 @@ module Sidekiq
|
|
35
35
|
@bucket_name = args.fetch(:bucket_name)
|
36
36
|
@job_class = args.fetch(:job_class, job.item["class"])
|
37
37
|
@error_class = args.fetch(:error_class, job.item["error_class"])
|
38
|
+
@error_msg = shorten_error_msg(args.fetch(:error_message, job.item["error_message"]).to_s)
|
38
39
|
end
|
39
40
|
|
40
41
|
def ==(other)
|
41
42
|
job_class == other.job_class &&
|
42
43
|
time_elapsed_since_failure == other.time_elapsed_since_failure &&
|
43
44
|
error_class == other.error_class &&
|
45
|
+
error_msg == other.error_msg &&
|
44
46
|
bucket_name == other.bucket_name &&
|
45
47
|
job_eql?(other.job)
|
46
48
|
end
|
@@ -48,7 +50,13 @@ module Sidekiq
|
|
48
50
|
|
49
51
|
private
|
50
52
|
|
51
|
-
attr_writer :job_class, :time_elapsed_since_failure, :error_class, :bucket_name, :job
|
53
|
+
attr_writer :job_class, :time_elapsed_since_failure, :error_class, :error_message, :bucket_name, :job
|
54
|
+
|
55
|
+
def shorten_error_msg(msg)
|
56
|
+
max_error_msg_length = 30
|
57
|
+
|
58
|
+
msg.length > max_error_msg_length ? "#{msg[0, max_error_msg_length]}..." : msg
|
59
|
+
end
|
52
60
|
|
53
61
|
def job_eql?(other_job) # rubocop:disable Metrics/AbcSize
|
54
62
|
job.jid == other_job.jid &&
|
@@ -7,7 +7,7 @@ module Sidekiq
|
|
7
7
|
class JobFilter
|
8
8
|
class << self
|
9
9
|
def filter_dead_jobs(filters = {})
|
10
|
-
# filters can have keys in (job_class, error_class, bucket_name)
|
10
|
+
# filters can have keys in (job_class, error_class, error_msg, bucket_name)
|
11
11
|
dead_jobs = []
|
12
12
|
Sidekiq::Undertaker::DeadJob.for_each do |dead_job|
|
13
13
|
filter_passed = true
|
@@ -26,7 +26,8 @@ module Sidekiq
|
|
26
26
|
value.nil? ||
|
27
27
|
total_dead_bucket?(filter, value) ||
|
28
28
|
all_jobs?(filter, value) ||
|
29
|
-
all_errors?(filter, value)
|
29
|
+
all_errors?(filter, value) ||
|
30
|
+
all_error_msgs?(filter, value)
|
30
31
|
end
|
31
32
|
|
32
33
|
def total_dead_bucket?(filter, value)
|
@@ -40,6 +41,10 @@ module Sidekiq
|
|
40
41
|
def all_errors?(filter, value)
|
41
42
|
filter == "error_class" && value == "all"
|
42
43
|
end
|
44
|
+
|
45
|
+
def all_error_msgs?(filter, value)
|
46
|
+
filter == "error_msg" && value == "all"
|
47
|
+
end
|
43
48
|
end
|
44
49
|
end
|
45
50
|
end
|
@@ -2,15 +2,21 @@
|
|
2
2
|
|
3
3
|
require "sidekiq/undertaker/job_distributor"
|
4
4
|
require "sidekiq/undertaker/job_filter"
|
5
|
+
require "base64"
|
6
|
+
require "json"
|
7
|
+
require "zip"
|
5
8
|
|
6
9
|
module Sidekiq
|
7
10
|
module Undertaker
|
8
11
|
module WebExtension
|
12
|
+
# rubocop:disable Metrics/ModuleLength
|
9
13
|
module APIHelpers
|
14
|
+
EXPORT_CHUNK_SIZE = 2000
|
15
|
+
|
10
16
|
def show_filter
|
11
17
|
store_request_params
|
12
18
|
|
13
|
-
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(
|
19
|
+
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(parsed_params)
|
14
20
|
@distribution = Sidekiq::Undertaker::JobDistributor.new(@dead_jobs).group_by_job_class
|
15
21
|
@total_dead = @dead_jobs.size
|
16
22
|
|
@@ -20,17 +26,27 @@ module Sidekiq
|
|
20
26
|
def show_filter_by_job_class_bucket_name
|
21
27
|
store_request_params
|
22
28
|
|
23
|
-
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(
|
29
|
+
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(parsed_params)
|
24
30
|
@distribution = Sidekiq::Undertaker::JobDistributor.new(@dead_jobs).group_by_error_class
|
25
31
|
@total_dead = @dead_jobs.size
|
26
32
|
|
27
33
|
render_result("filter_job_class.erb")
|
28
34
|
end
|
29
35
|
|
30
|
-
def
|
36
|
+
def show_filter_by_job_class_error_class_bucket_name
|
37
|
+
store_request_params
|
38
|
+
|
39
|
+
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(parsed_params)
|
40
|
+
@distribution = Sidekiq::Undertaker::JobDistributor.new(@dead_jobs).group_by_error_msg
|
41
|
+
@total_dead = @dead_jobs.size
|
42
|
+
|
43
|
+
render_result("filter_job_class_error_class.erb")
|
44
|
+
end
|
45
|
+
|
46
|
+
def show_undertaker_by_job_class_error_class_error_msg_bucket_name
|
31
47
|
store_request_params
|
32
48
|
|
33
|
-
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(
|
49
|
+
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(parsed_params)
|
34
50
|
|
35
51
|
# Display dead jobs as list
|
36
52
|
@dead_jobs = @dead_jobs.map(&:job)
|
@@ -39,7 +55,7 @@ module Sidekiq
|
|
39
55
|
|
40
56
|
# Pagination
|
41
57
|
@total_dead = @dead_jobs.size
|
42
|
-
@current_page = (
|
58
|
+
@current_page = (parsed_params[:page] || 1).to_i
|
43
59
|
@count = 50 # per page
|
44
60
|
@dead_jobs = @dead_jobs[((@current_page - 1) * @count), @count]
|
45
61
|
|
@@ -52,32 +68,36 @@ module Sidekiq
|
|
52
68
|
params.delete("job_class")
|
53
69
|
params.delete("bucket_name")
|
54
70
|
params.delete("error_class")
|
71
|
+
params.delete("error_msg")
|
55
72
|
|
56
73
|
render_result("morgue.erb")
|
57
74
|
end
|
58
75
|
|
59
76
|
def post_undertaker
|
60
|
-
raise ::ArgumentError.new("Key missing") unless
|
61
|
-
|
62
|
-
params["key"].each do |key|
|
63
|
-
job = Sidekiq::DeadSet.new.fetch(*parse_params(key)).first
|
64
|
-
if job
|
65
|
-
if params["retry"]
|
66
|
-
job.retry
|
67
|
-
elsif params["delete"]
|
68
|
-
job.delete
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
77
|
+
raise ::ArgumentError.new("Key missing") unless parsed_params["key"]
|
72
78
|
|
73
|
-
|
79
|
+
jobs = parsed_params["key"].map { |k| Sidekiq::DeadSet.new.fetch(*parse_params(k)).first }.compact
|
80
|
+
|
81
|
+
handle_selected_jobs jobs
|
74
82
|
rescue ::ArgumentError
|
75
83
|
bad_request
|
76
84
|
end
|
77
85
|
|
78
|
-
def
|
86
|
+
def handle_selected_jobs(jobs)
|
87
|
+
return send_data(*prepare_data(jobs.map(&:item), EXPORT_CHUNK_SIZE)) if parsed_params["export"]
|
88
|
+
|
89
|
+
if parsed_params["retry"]
|
90
|
+
jobs.each(&:retry)
|
91
|
+
elsif parsed_params["delete"]
|
92
|
+
jobs.each(&:delete)
|
93
|
+
end
|
94
|
+
|
95
|
+
redirect redirect_path(request)
|
96
|
+
end
|
97
|
+
|
98
|
+
def post_undertaker_job_class_error_class_error_msg_bucket_name_delete
|
79
99
|
store_request_params
|
80
|
-
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(
|
100
|
+
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(parsed_params)
|
81
101
|
@dead_jobs.each do |dead_job|
|
82
102
|
dead_job.job.delete
|
83
103
|
end
|
@@ -85,10 +105,10 @@ module Sidekiq
|
|
85
105
|
redirect redirect_path(request)
|
86
106
|
end
|
87
107
|
|
88
|
-
def
|
108
|
+
def post_undertaker_job_class_error_class_error_msg_bucket_name_retry
|
89
109
|
store_request_params
|
90
110
|
|
91
|
-
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(
|
111
|
+
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(parsed_params)
|
92
112
|
@dead_jobs.each do |dead_job|
|
93
113
|
dead_job.job.retry
|
94
114
|
end
|
@@ -96,14 +116,45 @@ module Sidekiq
|
|
96
116
|
redirect redirect_path(request)
|
97
117
|
end
|
98
118
|
|
119
|
+
def post_undertaker_job_class_error_class_error_msg_bucket_name_export
|
120
|
+
store_request_params
|
121
|
+
|
122
|
+
@dead_jobs = Sidekiq::Undertaker::JobFilter.filter_dead_jobs(parsed_params)
|
123
|
+
send_data(*prepare_data(@dead_jobs.map { |j| j.job.item }, EXPORT_CHUNK_SIZE))
|
124
|
+
end
|
125
|
+
|
126
|
+
def post_import_jobs
|
127
|
+
file = parsed_params["upload_file"]
|
128
|
+
raise ::ArgumentError.new("The file is not a json") if file.nil? || file[:type] != "application/json"
|
129
|
+
|
130
|
+
data = parsed_params["upload_file"][:tempfile].read
|
131
|
+
dead_set = Sidekiq::DeadSet.new
|
132
|
+
|
133
|
+
JSON.parse(data).each do |job|
|
134
|
+
dead_set.kill(Sidekiq.dump_json(job))
|
135
|
+
end
|
136
|
+
redirect redirect_path(request)
|
137
|
+
rescue StandardError
|
138
|
+
bad_request
|
139
|
+
end
|
140
|
+
|
99
141
|
def render_result(template)
|
100
142
|
render(:erb, File.read(File.join(view_path, template)))
|
101
143
|
end
|
102
144
|
|
103
145
|
def store_request_params
|
104
|
-
@req_job_class =
|
105
|
-
@req_bucket_name =
|
106
|
-
@req_error_class =
|
146
|
+
@req_job_class = parsed_params["job_class"]
|
147
|
+
@req_bucket_name = parsed_params["bucket_name"]
|
148
|
+
@req_error_class = parsed_params["error_class"]
|
149
|
+
@req_error_msg = parsed_params["error_msg"]
|
150
|
+
end
|
151
|
+
|
152
|
+
def parsed_params
|
153
|
+
@parsed_params ||= if params["error_msg"] && params["error_msg"] != "all"
|
154
|
+
params.merge("error_msg" => Base64.urlsafe_decode64(params["error_msg"]))
|
155
|
+
else
|
156
|
+
params
|
157
|
+
end
|
107
158
|
end
|
108
159
|
|
109
160
|
def view_path
|
@@ -112,13 +163,40 @@ module Sidekiq
|
|
112
163
|
|
113
164
|
def redirect_path(request)
|
114
165
|
path = request.referer ? URI.parse(request.referer).path : request.path
|
115
|
-
path.gsub("/delete", "").gsub("/retry", "")
|
166
|
+
path.gsub("/delete", "").gsub("/retry", "").gsub("/export", "")
|
167
|
+
end
|
168
|
+
|
169
|
+
def prepare_data(data, chunk_size)
|
170
|
+
filename = Time.now.strftime("%Y-%m-%d_%H-%M").to_s
|
171
|
+
return [data.to_json, "application/json", "#{filename}.json"] if data.length <= chunk_size
|
172
|
+
|
173
|
+
filename = "#{@req_job_class}_#{filename}"
|
174
|
+
zip = Zip::OutputStream.write_buffer do |file|
|
175
|
+
data.each_slice(chunk_size).each_with_index do |chunk, index|
|
176
|
+
file.put_next_entry("#{filename}_part-#{index + 1}.json")
|
177
|
+
file.write chunk.to_json
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
[zip.string, "application/zip", "#{filename}.zip"]
|
182
|
+
end
|
183
|
+
|
184
|
+
def send_data(data, content_type = "text/plain", file_name = "attachment.txt")
|
185
|
+
[
|
186
|
+
200,
|
187
|
+
{
|
188
|
+
"Content-Type" => content_type,
|
189
|
+
"Content-Disposition" => "attachment; filename=\"#{file_name}\""
|
190
|
+
},
|
191
|
+
[data]
|
192
|
+
]
|
116
193
|
end
|
117
194
|
|
118
195
|
def bad_request
|
119
196
|
[400, { "Content-Type" => "text/plain" }, ["Bad Request"]]
|
120
197
|
end
|
121
198
|
end
|
199
|
+
# rubocop:enable Metrics/ModuleLength
|
122
200
|
end
|
123
201
|
end
|
124
202
|
end
|
@@ -12,25 +12,34 @@ module Sidekiq
|
|
12
12
|
app.get "/undertaker/filter" do
|
13
13
|
show_filter
|
14
14
|
end
|
15
|
-
|
16
15
|
app.get "/undertaker/filter/:job_class/:bucket_name" do
|
17
16
|
show_filter_by_job_class_bucket_name
|
18
17
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
app.get "/undertaker/filter/:job_class/:error_class/:bucket_name" do
|
19
|
+
show_filter_by_job_class_error_class_bucket_name
|
20
|
+
end
|
21
|
+
app.get "/undertaker/morgue/:job_class/:error_class/:error_msg/:bucket_name" do
|
22
|
+
show_undertaker_by_job_class_error_class_error_msg_bucket_name
|
22
23
|
end
|
23
24
|
|
24
25
|
app.post "/undertaker/morgue" do
|
25
26
|
post_undertaker
|
26
27
|
end
|
27
28
|
|
28
|
-
app.post "/undertaker/morgue/:job_class/:error_class/:bucket_name/delete" do
|
29
|
-
|
29
|
+
app.post "/undertaker/morgue/:job_class/:error_class/:error_msg/:bucket_name/delete" do
|
30
|
+
post_undertaker_job_class_error_class_error_msg_bucket_name_delete
|
31
|
+
end
|
32
|
+
|
33
|
+
app.post "/undertaker/morgue/:job_class/:error_class/:error_msg/:bucket_name/retry" do
|
34
|
+
post_undertaker_job_class_error_class_error_msg_bucket_name_retry
|
35
|
+
end
|
36
|
+
|
37
|
+
app.post "/undertaker/morgue/:job_class/:error_class/:error_msg/:bucket_name/export" do
|
38
|
+
post_undertaker_job_class_error_class_error_msg_bucket_name_export
|
30
39
|
end
|
31
40
|
|
32
|
-
app.post "/undertaker/
|
33
|
-
|
41
|
+
app.post "/undertaker/import_jobs" do
|
42
|
+
post_import_jobs
|
34
43
|
end
|
35
44
|
end
|
36
45
|
# rubocop:enable Metrics/MethodLength
|
data/sidekiq-undertaker.gemspec
CHANGED
@@ -21,8 +21,9 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.metadata = {
|
22
22
|
"homepage_uri" => "https://github.com/ThomasKoppensteiner/sidekiq-undertaker",
|
23
23
|
"source_code_uri" => "https://github.com/ThomasKoppensteiner/sidekiq-undertaker",
|
24
|
+
"changelog_uri" => "https://github.com/ThomasKoppensteiner/sidekiq-undertaker/blob/master/CHANGELOG.md",
|
24
25
|
"bug_tracker_uri" => "https://github.com/ThomasKoppensteiner/sidekiq-undertaker/issues",
|
25
|
-
"build_status_uri" => "https://
|
26
|
+
"build_status_uri" => "https://github.com/ThomasKoppensteiner/sidekiq-undertaker/actions/workflows/ruby-build.yml",
|
26
27
|
"rubygems_mfa_required" => "true"
|
27
28
|
}
|
28
29
|
|
@@ -30,7 +31,6 @@ Gem::Specification.new do |spec|
|
|
30
31
|
|
31
32
|
spec.files = `git ls-files -z`.split("\x0")
|
32
33
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
33
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
34
34
|
spec.require_paths = ["lib", "lib/sidekiq/undertaker"]
|
35
35
|
|
36
36
|
spec.add_development_dependency "bundler", ">= 1.17", "<3"
|
@@ -46,13 +46,14 @@ Gem::Specification.new do |spec|
|
|
46
46
|
spec.add_development_dependency "rspec-mocks", "~> 3.8"
|
47
47
|
spec.add_development_dependency "rspec-sidekiq", "~> 3.0"
|
48
48
|
spec.add_development_dependency "rt_rubocop_defaults", "~> 2.3"
|
49
|
-
spec.add_development_dependency "rubocop", "~> 1.
|
49
|
+
spec.add_development_dependency "rubocop", "~> 1.30"
|
50
50
|
spec.add_development_dependency "rubocop-rake", "~> 0.5"
|
51
51
|
spec.add_development_dependency "rubocop-rspec", "~> 2.0"
|
52
52
|
spec.add_development_dependency "rubocop_runner", "~> 2.1"
|
53
|
-
spec.add_development_dependency "simplecov", "~> 0.
|
53
|
+
spec.add_development_dependency "simplecov", "~> 0.21"
|
54
54
|
spec.add_development_dependency "sinatra", "~> 2.0"
|
55
55
|
spec.add_development_dependency "timecop", "~> 0.9"
|
56
56
|
|
57
|
-
spec.add_runtime_dependency "
|
57
|
+
spec.add_runtime_dependency "rubyzip", "~> 2.3"
|
58
|
+
spec.add_runtime_dependency "sidekiq", ">= 6.4", "< 7"
|
58
59
|
end
|