resque-integration 3.4.1 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.drone.yml +65 -19
- data/Appraisals +6 -11
- data/CHANGELOG.md +33 -2
- data/Gemfile +2 -0
- data/dip.yml +3 -2
- data/docker-compose.yml +7 -0
- data/lib/resque/integration.rb +19 -18
- data/lib/resque/integration/configuration.rb +18 -0
- data/lib/resque/integration/engine.rb +1 -1
- data/lib/resque/integration/ordered.rb +27 -0
- data/lib/resque/integration/tasks/hooks.rake +12 -2
- data/lib/resque/integration/tasks/resque.rake +1 -1
- data/lib/resque/integration/unique.rb +5 -1
- data/lib/resque/integration/version.rb +1 -1
- data/resque-integration.gemspec +2 -1
- data/spec/internal/app/jobs/retries_argument_error_job.rb +10 -0
- data/spec/internal/app/jobs/retries_job.rb +10 -0
- data/spec/internal/app/jobs/retries_standard_error_job.rb +10 -0
- data/spec/internal/app/services/dummy_for_retries_service.rb +5 -0
- data/spec/resque/integration/configuration_spec.rb +12 -0
- data/spec/resque/integration/ordered_spec.rb +57 -0
- data/spec/resque/integration_spec.rb +61 -16
- data/spec/spec_helper.rb +3 -2
- metadata +24 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d37c0511fee9c3f766f352cb18ef36c4980cc869
|
4
|
+
data.tar.gz: d8dd5259944ac4ed274530171bda477551bb9f09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09ee9d7d3640eb5138138bc941064adcb19cb0ef817d90048613c2cb9c1bb01546ea428b6f10f5ab13b0a874b6289a7ae1ecaead8b36a8fd443c4cba16decf77'
|
7
|
+
data.tar.gz: 5bdbe905a197ac686192ca05b192a3e64808a0c676498366b3c18ca7cd8ec4a638d0576aab0f7c77ab7eeb0f72a54698d83d46bf2c68e3324fa23410235d5600
|
data/.drone.yml
CHANGED
@@ -1,28 +1,74 @@
|
|
1
|
-
build
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
name: build
|
2
|
+
|
3
|
+
kind: pipeline
|
4
|
+
type: docker
|
5
|
+
|
6
|
+
volumes:
|
7
|
+
- name: images
|
8
|
+
host:
|
9
|
+
path: /home/data/drone/images
|
10
|
+
- name: bundle
|
11
|
+
host:
|
12
|
+
path: /home/data/drone/gems
|
13
|
+
- name: rubygems
|
14
|
+
host:
|
15
|
+
path: /home/data/drone/rubygems
|
16
|
+
|
17
|
+
spec_step_common: &spec_step_common
|
18
|
+
image: abakpress/dind-testing:1.0.3
|
19
|
+
pull: if-not-exists
|
20
|
+
privileged: true
|
21
|
+
volumes:
|
22
|
+
- name: images
|
23
|
+
path: /images
|
24
|
+
- name: bundle
|
25
|
+
path: /bundle
|
26
|
+
commands:
|
27
|
+
- prepare-build
|
28
|
+
|
29
|
+
- fetch-images
|
30
|
+
--image abakpress/ruby-app:$RUBY_IMAGE_TAG
|
31
|
+
--image redis:$REDIS_IMAGE_TAG
|
32
|
+
- dip provision
|
33
|
+
- dip rspec
|
34
|
+
|
35
|
+
steps:
|
36
|
+
- name: Tests Ruby 2.2
|
9
37
|
environment:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
38
|
+
COMPOSE_FILE_EXT: drone
|
39
|
+
DOCKER_RUBY_VERSION: 2.2
|
40
|
+
RUBY_IMAGE_TAG: 2.2-latest
|
41
|
+
REDIS_IMAGE_TAG: 4-alpine
|
42
|
+
RAILS_ENV: test
|
43
|
+
<<: *spec_step_common
|
14
44
|
|
15
|
-
|
16
|
-
|
17
|
-
|
45
|
+
- name: Tests Ruby 2.3
|
46
|
+
environment:
|
47
|
+
COMPOSE_FILE_EXT: drone
|
48
|
+
DOCKER_RUBY_VERSION: 2.3
|
49
|
+
RUBY_IMAGE_TAG: 2.3-latest
|
50
|
+
REDIS_IMAGE_TAG: 4-alpine
|
51
|
+
RAILS_ENV: test
|
52
|
+
<<: *spec_step_common
|
53
|
+
|
54
|
+
- name: Tests Ruby 2.4
|
55
|
+
environment:
|
56
|
+
COMPOSE_FILE_EXT: drone
|
57
|
+
DOCKER_RUBY_VERSION: 2.4
|
58
|
+
RUBY_IMAGE_TAG: 2.4-latest
|
59
|
+
REDIS_IMAGE_TAG: 4-alpine
|
60
|
+
RAILS_ENV: test
|
61
|
+
<<: *spec_step_common
|
18
62
|
|
19
|
-
release
|
20
|
-
image: abakpress/gem-publication
|
21
|
-
pull:
|
63
|
+
- name: release
|
64
|
+
image: abakpress/gem-publication:latest
|
65
|
+
pull: if-not-exists
|
22
66
|
when:
|
23
67
|
event: push
|
24
68
|
branch: master
|
69
|
+
status: success
|
25
70
|
volumes:
|
26
|
-
-
|
71
|
+
- name: rubygems
|
72
|
+
path: /root/.gem
|
27
73
|
commands:
|
28
74
|
- release-gem --public
|
data/Appraisals
CHANGED
@@ -1,13 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
appraise 'rails4.0' do
|
6
|
-
gem 'rails', '~> 4.0.13'
|
7
|
-
end
|
8
|
-
|
9
|
-
appraise 'rails4.1' do
|
10
|
-
gem 'rails', '~> 4.1.16'
|
1
|
+
if RUBY_VERSION < '2.4'
|
2
|
+
appraise 'rails4.0' do
|
3
|
+
gem 'rails', '~> 4.0.13'
|
4
|
+
end
|
11
5
|
end
|
12
6
|
|
13
7
|
appraise 'rails4.2' do
|
@@ -23,5 +17,6 @@ appraise 'rails5.1' do
|
|
23
17
|
end
|
24
18
|
|
25
19
|
appraise 'rails5.2' do
|
26
|
-
gem 'rails', '~> 5.2.0'
|
20
|
+
gem 'rails', '~> 5.2.0', '< 5.2.4.1'
|
21
|
+
gem 'mimemagic', '<= 0.3.9' if RUBY_VERSION < '2.3'
|
27
22
|
end
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,38 @@
|
|
1
|
-
# v3.
|
2
|
-
|
1
|
+
# v3.8.0
|
2
|
+
|
3
|
+
* 2021-08-19 [27ad006](../../commit/27ad006) - __(Andrew N. Shalaev)__ Release v3.8.0
|
4
|
+
* 2021-08-19 [03eab18](../../commit/03eab18) - __(Andrew N. Shalaev)__ fix: use Redis#exists? for get boolean value
|
5
|
+
* 2021-07-22 [0caf11c](../../commit/0caf11c) - __(TamarinEA)__ chore: fetch redis image and add rubygems volume
|
6
|
+
* 2021-07-21 [7b94d0e](../../commit/7b94d0e) - __(TamarinEA)__ chore: release public gem
|
7
|
+
* 2021-07-20 [c51d9ab](../../commit/c51d9ab) - __(TamarinEA)__ chore: lock mimemagic for ruby 2.2
|
8
|
+
* 2021-07-20 [843c787](../../commit/843c787) - __(TamarinEA)__ Release 3.7.1
|
9
|
+
* 2021-07-20 [933115d](../../commit/933115d) - __(TamarinEA)__ chore: use redis image istead of mock
|
10
|
+
* 2021-07-20 [21aa6ba](../../commit/21aa6ba) - __(TamarinEA)__ chore: add ruby 2.4 support
|
11
|
+
* 2020-10-05 [05e046b](../../commit/05e046b) - __(TamarinEA)__ Relesae 3.7.0
|
12
|
+
* 2020-10-05 [6f12054](../../commit/6f12054) - __(Andrew N. Shalaev)__ Release v3.6.0
|
13
|
+
* 2020-09-04 [ee6104e](../../commit/ee6104e) - __(Zhidkov Denis)__ fix: change resque restart command to avoid unwatched workers appearance
|
14
|
+
https://jira.railsc.ru/browse/BPC-17334
|
15
|
+
|
16
|
+
* 2020-08-30 [7676652](../../commit/7676652) - __(TamarinEA)__ feature: add ordered queue check
|
17
|
+
https://jira.railsc.ru/browse/GOODS-2471
|
18
|
+
|
19
|
+
* 2020-04-20 [d36e4b2](../../commit/d36e4b2) - __(TamarinEA)__ chore: use drone 1.6
|
20
|
+
* 2020-04-19 [e33faa6](../../commit/e33faa6) - __(TamarinEA)__ Release 3.5.2
|
21
|
+
* 2020-04-16 [35eafa2](../../commit/35eafa2) - __(TamarinEA)__ fix: reload ordered meta before save
|
22
|
+
https://jira.railsc.ru/browse/GOODS-2326
|
23
|
+
|
24
|
+
* 2020-04-16 [0c53eef](../../commit/0c53eef) - __(TamarinEA)__ chore: lock gems for support ruby 2.2
|
25
|
+
* 2018-12-21 [c2b890d](../../commit/c2b890d) - __(Andrew N. Shalaev)__ Release v3.5.1
|
26
|
+
* 2018-12-21 [d7478c2](../../commit/d7478c2) - __(Andrew N. Shalaev)__ fix: add support for redis >= v4
|
27
|
+
* 2018-09-06 [49717a5](../../commit/49717a5) - __(Mikhail Nelaev)__ Release 3.5.0
|
3
28
|
* 2018-08-21 [b56dcc8](../../commit/b56dcc8) - __(Artem Napolskih)__ chore: Add automatic publication
|
4
29
|
* 2018-08-15 [5e90b55](../../commit/5e90b55) - __(Artem Napolskih)__ feat: rails 5-x support added
|
30
|
+
* 2018-08-09 [3fa8ce0](../../commit/3fa8ce0) - __(terentev)__ feat: move temporary_exceptions to yml config
|
31
|
+
https://jira.railsc.ru/browse/GOODS-1418
|
32
|
+
|
33
|
+
* 2018-08-02 [528feab](../../commit/528feab) - __(terentev)__ feat: adds ability for retry jobs after temporary errors
|
34
|
+
https://jira.railsc.ru/browse/GOODS-1418
|
35
|
+
|
5
36
|
* 2018-06-05 [3fc2608](../../commit/3fc2608) - __(Pavel Galkin)__ Release 3.4.0
|
6
37
|
* 2018-06-05 [6ec7a38](../../commit/6ec7a38) - __(Pavel Galkin)__ feat: resque:expire task
|
7
38
|
https://jira.railsc.ru/browse/PC4-21225
|
data/Gemfile
CHANGED
data/dip.yml
CHANGED
data/docker-compose.yml
CHANGED
@@ -5,6 +5,13 @@ services:
|
|
5
5
|
image: abakpress/ruby-app:$RUBY_IMAGE_TAG
|
6
6
|
environment:
|
7
7
|
- BUNDLE_PATH=/bundle/$DOCKER_RUBY_VERSION
|
8
|
+
- TEST_REDIS_HOST=redis
|
8
9
|
command: bash
|
9
10
|
volumes:
|
10
11
|
- .:/app
|
12
|
+
depends_on:
|
13
|
+
- redis
|
14
|
+
|
15
|
+
redis:
|
16
|
+
image: redis:$REDIS_IMAGE_TAG
|
17
|
+
command: 'redis-server --bind 0.0.0.0'
|
data/lib/resque/integration.rb
CHANGED
@@ -100,33 +100,34 @@ module Resque
|
|
100
100
|
|
101
101
|
# Extend resque-retry.
|
102
102
|
#
|
103
|
-
# options - Hash
|
103
|
+
# options - Hash of retry options (default: {}):
|
104
|
+
# :limit - Integer max number of retry attempts (default: 2)
|
105
|
+
# :delay - Integer seconds between retry attempts (default: 60)
|
106
|
+
# :exceptions - Array or Hash of specific exceptions to retry (optional)
|
107
|
+
# :temporary - boolean retry on temporary exceptions list (default: false)
|
108
|
+
# :expire_retry_key_after - Integer expire of retry key in redis (default: 3200)
|
104
109
|
#
|
105
|
-
#
|
106
|
-
# :delay - Integer (default: 60)
|
107
|
-
# :expire_retry_key_after - Integer (default: 3200), истечение ключа в секундах. Если
|
108
|
-
#
|
109
|
-
# t - среднее время выполнения одного джоба
|
110
|
-
# n - текущее кол-во джобов в очереди
|
111
|
-
# k - кол-во воркеров
|
112
|
-
#
|
113
|
-
# то expire_retry_key_after >= t * n / k
|
114
|
-
#
|
115
|
-
# Иначе ключ истечет, прежде чем джоб отработает.
|
116
|
-
#
|
117
|
-
#
|
118
|
-
# Returns nothing
|
110
|
+
# Returns nothing.
|
119
111
|
def retrys(options = {})
|
120
|
-
if unique?
|
121
|
-
raise '`retrys` should be declared higher in code than `unique`'
|
122
|
-
end
|
112
|
+
raise '`retries` should be declared higher in code than `unique`' if unique?
|
123
113
|
|
124
114
|
extend Resque::Plugins::Retry
|
125
115
|
|
126
116
|
@retry_limit = options.fetch(:limit, 2)
|
127
117
|
@retry_delay = options.fetch(:delay, 60)
|
118
|
+
|
119
|
+
@retry_exceptions = options[:exceptions] if options.key? :exceptions
|
120
|
+
|
121
|
+
if options[:temporary]
|
122
|
+
@retry_exceptions = @retry_exceptions && @retry_exceptions.dup || {}
|
123
|
+
@retry_exceptions = @retry_exceptions.product([@retry_delay]).to_h if @retry_exceptions.is_a? Array
|
124
|
+
|
125
|
+
@retry_exceptions.reverse_merge!(Resque.config.temporary_exceptions)
|
126
|
+
end
|
127
|
+
|
128
128
|
@expire_retry_key_after = options.fetch(:expire_retry_key_after, 1.hour.seconds)
|
129
129
|
end
|
130
|
+
alias retries retrys
|
130
131
|
|
131
132
|
# Mark Job as ordered
|
132
133
|
def ordered(options = {})
|
@@ -209,6 +209,24 @@ module Resque
|
|
209
209
|
self['resque.god_log_level'] || 'info'
|
210
210
|
end
|
211
211
|
|
212
|
+
# Public: Temporary exceptions.
|
213
|
+
#
|
214
|
+
# Examples
|
215
|
+
#
|
216
|
+
# temporary_exceptions
|
217
|
+
# # => {PG::TRDeadlockDetected => 20, Net::OpenTimeout => 123}
|
218
|
+
#
|
219
|
+
# Returns Hash.
|
220
|
+
def temporary_exceptions
|
221
|
+
return @temporary_exceptions if defined?(@temporary_exceptions)
|
222
|
+
|
223
|
+
return {} unless self['resque.temporary_exceptions']
|
224
|
+
|
225
|
+
@temporary_exceptions = self['resque.temporary_exceptions'].each_with_object({}) do |(key, value), result|
|
226
|
+
result[key.constantize] = value
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
212
230
|
private
|
213
231
|
def load(path)
|
214
232
|
if File.exists?(path)
|
@@ -112,12 +112,14 @@ module Resque
|
|
112
112
|
begin
|
113
113
|
execute(ordered_meta, *job_args)
|
114
114
|
rescue Exception
|
115
|
+
ordered_meta.reload!
|
115
116
|
ordered_meta.fail!
|
116
117
|
raise
|
117
118
|
ensure
|
118
119
|
uniqueness.remove(meta_id, job_args) if uniqueness
|
119
120
|
end
|
120
121
|
|
122
|
+
ordered_meta.reload!
|
121
123
|
ordered_meta.finish!
|
122
124
|
|
123
125
|
i += 1
|
@@ -137,6 +139,31 @@ module Resque
|
|
137
139
|
def ordered_meta_id(args)
|
138
140
|
Digest::SHA1.hexdigest([Time.now.to_f, rand, self, args].join)
|
139
141
|
end
|
142
|
+
|
143
|
+
def in_ordered_queue?(*args)
|
144
|
+
meta = enqueued?(*args)
|
145
|
+
return false unless meta
|
146
|
+
|
147
|
+
decoded_args = Resque.decode(Resque.encode(args))
|
148
|
+
|
149
|
+
args_key = ordered_queue_key(meta.meta_id)
|
150
|
+
|
151
|
+
args_meta_id = nil
|
152
|
+
|
153
|
+
::Resque.redis.lrange(args_key, 0, -1).each do |job_args|
|
154
|
+
job_args = ::Resque.decode(job_args)
|
155
|
+
meta_id = job_args.shift
|
156
|
+
|
157
|
+
if job_args == decoded_args
|
158
|
+
args_meta_id = meta_id
|
159
|
+
break
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
return false unless args_meta_id
|
164
|
+
|
165
|
+
get_meta(args_meta_id)
|
166
|
+
end
|
140
167
|
end
|
141
168
|
end
|
142
169
|
end
|
@@ -26,7 +26,12 @@ namespace :resque do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
Resque.before_fork do
|
29
|
-
|
29
|
+
client = if Gem::Version.new(::Redis::VERSION) < Gem::Version.new('4')
|
30
|
+
Resque.redis.client
|
31
|
+
else
|
32
|
+
Resque.redis._client
|
33
|
+
end
|
34
|
+
client.disconnect
|
30
35
|
|
31
36
|
ActiveRecord::Base.connection_handler.clear_all_connections!
|
32
37
|
end
|
@@ -36,7 +41,12 @@ namespace :resque do
|
|
36
41
|
|
37
42
|
ActiveRecord::Base.establish_connection
|
38
43
|
|
39
|
-
|
44
|
+
client = if Gem::Version.new(::Redis::VERSION) < Gem::Version.new('4')
|
45
|
+
Resque.redis.client
|
46
|
+
else
|
47
|
+
Resque.redis._client
|
48
|
+
end
|
49
|
+
client.connect
|
40
50
|
end
|
41
51
|
|
42
52
|
# Support for resque-multi-job-forks
|
@@ -20,7 +20,7 @@ namespace :resque do
|
|
20
20
|
if god_stopped?
|
21
21
|
Rake::Task['resque:start'].invoke
|
22
22
|
else
|
23
|
-
puts `#{god} load #{Resque.config.config_file} stop && #{god}
|
23
|
+
puts `#{god} stop resque && #{god} load #{Resque.config.config_file} stop && #{god} start resque`
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -165,8 +165,12 @@ module Resque
|
|
165
165
|
end
|
166
166
|
|
167
167
|
# Returns true if resque job is in locked state
|
168
|
+
#
|
169
|
+
# Returns Boolean
|
168
170
|
def locked?(*args)
|
169
|
-
::Resque.redis
|
171
|
+
redis = ::Resque.redis
|
172
|
+
|
173
|
+
redis.respond_to?(:exists?) ? redis.exists?(lock_id(*args)) : redis.exists(lock_id(*args))
|
170
174
|
end
|
171
175
|
|
172
176
|
# Dequeue unique job
|
data/resque-integration.gemspec
CHANGED
@@ -28,13 +28,14 @@ Gem::Specification.new do |gem|
|
|
28
28
|
gem.add_runtime_dependency 'multi_json'
|
29
29
|
gem.add_runtime_dependency 'rake'
|
30
30
|
|
31
|
+
gem.add_runtime_dependency 'redis'
|
32
|
+
|
31
33
|
gem.add_development_dependency 'bundler'
|
32
34
|
gem.add_development_dependency 'rspec', '~> 2.14'
|
33
35
|
gem.add_development_dependency 'rspec-its'
|
34
36
|
gem.add_development_dependency 'simplecov'
|
35
37
|
gem.add_development_dependency 'appraisal', '>= 1.0.2'
|
36
38
|
gem.add_development_dependency 'combustion', '>= 0.5.5'
|
37
|
-
gem.add_development_dependency 'mock_redis'
|
38
39
|
gem.add_development_dependency 'timecop'
|
39
40
|
gem.add_development_dependency 'pry-byebug'
|
40
41
|
end
|
@@ -54,6 +54,18 @@ describe Resque::Integration::Configuration do
|
|
54
54
|
it { expect(config.run_at_exit_hooks?).to be_falsey }
|
55
55
|
end
|
56
56
|
end
|
57
|
+
|
58
|
+
describe '#temporary_exceptions' do
|
59
|
+
context 'when default' do
|
60
|
+
it { expect(config.temporary_exceptions).to eq({}) }
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when defined' do
|
64
|
+
let(:config_yaml) { {'resque' => {'temporary_exceptions' => {'StandardError' => 12}}} }
|
65
|
+
|
66
|
+
it { expect(config.temporary_exceptions).to eq(StandardError => 12) }
|
67
|
+
end
|
68
|
+
end
|
57
69
|
end
|
58
70
|
|
59
71
|
describe Resque::Integration::Configuration::Notifier do
|
@@ -6,6 +6,15 @@ describe Resque::Integration::Ordered do
|
|
6
6
|
|
7
7
|
unique { |company_id, param1| [company_id] }
|
8
8
|
ordered max_iterations: 2
|
9
|
+
|
10
|
+
def self.execute(ordered_meta, arg1, arg2)
|
11
|
+
old_meta = @meta_id
|
12
|
+
@meta_id = ordered_meta.meta_id
|
13
|
+
|
14
|
+
at(arg1, arg2, 'some message')
|
15
|
+
|
16
|
+
@meta_id = old_meta
|
17
|
+
end
|
9
18
|
end
|
10
19
|
|
11
20
|
class UniqueTestJob
|
@@ -62,6 +71,16 @@ describe Resque::Integration::Ordered do
|
|
62
71
|
expect(TestJob.ordered_queue_size(meta_id)).to eq 2
|
63
72
|
end
|
64
73
|
|
74
|
+
it 'save ordered meta' do
|
75
|
+
ordered_meta_id = TestJob.enqueue(1, 10).meta_id
|
76
|
+
meta_id = TestJob.meta_id(1, 10)
|
77
|
+
TestJob.perform(meta_id)
|
78
|
+
ordered_meta = TestJob.get_meta(ordered_meta_id)
|
79
|
+
|
80
|
+
expect(ordered_meta).to be_finished
|
81
|
+
expect(ordered_meta.progress).to eq(num: 1, total: 10, percent: 10, message: 'some message')
|
82
|
+
end
|
83
|
+
|
65
84
|
context 'uniqueness' do
|
66
85
|
it 'perform with unique args only once' do
|
67
86
|
UniqueTestJob.enqueue(1, 10)
|
@@ -84,4 +103,42 @@ describe Resque::Integration::Ordered do
|
|
84
103
|
expect(meta.meta_id).to_not eq UniqueTestJob.enqueue(1, 20).meta_id
|
85
104
|
end
|
86
105
|
end
|
106
|
+
|
107
|
+
describe '#in_ordered_queue?' do
|
108
|
+
before do
|
109
|
+
allow(TestJob).to receive(:rand).and_return(123)
|
110
|
+
|
111
|
+
Timecop.freeze
|
112
|
+
end
|
113
|
+
|
114
|
+
it do
|
115
|
+
TestJob.enqueue(1, 10)
|
116
|
+
TestJob.enqueue(1, 20)
|
117
|
+
|
118
|
+
expect(TestJob.in_ordered_queue?(1, 10)).to be_instance_of(Resque::Plugins::Meta::Metadata)
|
119
|
+
expect(TestJob.in_ordered_queue?(1, 10).meta_id).to eq TestJob.ordered_meta_id([1, 10])
|
120
|
+
expect(TestJob.in_ordered_queue?(1, 20)).to be_instance_of(Resque::Plugins::Meta::Metadata)
|
121
|
+
expect(TestJob.in_ordered_queue?(1, 20).meta_id).to eq TestJob.ordered_meta_id([1, 20])
|
122
|
+
expect(TestJob.in_ordered_queue?(1, 30)).to be_falsey
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'when some complex arg' do
|
126
|
+
let(:complex_arg) { [Integer, {a: 1, 'b' => '2'}, 10] }
|
127
|
+
|
128
|
+
it do
|
129
|
+
expect(TestJob.in_ordered_queue?(1, complex_arg)).to be_falsey
|
130
|
+
|
131
|
+
TestJob.enqueue(1, complex_arg)
|
132
|
+
|
133
|
+
expect(TestJob.in_ordered_queue?(1, complex_arg)).to be_instance_of(Resque::Plugins::Meta::Metadata)
|
134
|
+
expect(TestJob.in_ordered_queue?(1, complex_arg).meta_id).to eq TestJob.ordered_meta_id([1, complex_arg])
|
135
|
+
|
136
|
+
TestJob.perform(TestJob.meta_id(1, complex_arg))
|
137
|
+
|
138
|
+
expect(TestJob.in_ordered_queue?(1, complex_arg)).to be_falsey
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
after { Timecop.return }
|
143
|
+
end
|
87
144
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
require 'spec_helper'
|
3
2
|
|
4
3
|
RSpec.describe Resque::Integration do
|
@@ -38,34 +37,49 @@ RSpec.describe Resque::Integration do
|
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
41
|
-
|
42
|
-
|
40
|
+
let(:redis) { Resque.redis }
|
41
|
+
let(:travel_redis) do
|
42
|
+
->(time) do
|
43
|
+
redis.keys.each do |key|
|
44
|
+
ttl = redis.ttl(key)
|
45
|
+
next if ttl <= 0
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
expect(Resque.peek(:test, 0, 100).size).to eq(1)
|
47
|
+
redis.expire(key, ttl - time.to_i)
|
48
|
+
end
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
51
|
-
|
52
|
-
|
52
|
+
context 'when enqueues only one job' do
|
53
|
+
before do
|
54
|
+
UniqueJob.enqueue(1, param: 'one')
|
53
55
|
|
54
|
-
|
55
|
-
UniqueJob.enqueue(1, param: 'two')
|
56
|
+
travel_redis.call(10.hours)
|
56
57
|
|
57
|
-
|
58
|
+
UniqueJob.enqueue(1, param: 'one')
|
58
59
|
end
|
60
|
+
|
61
|
+
it { expect(Resque.peek(:test, 0, 100).size).to eq(1) }
|
59
62
|
end
|
60
63
|
|
61
|
-
|
62
|
-
|
64
|
+
context 'when enqueues two jobs with differ args' do
|
65
|
+
before do
|
66
|
+
UniqueJob.enqueue(1, param: 'one')
|
67
|
+
UniqueJob.enqueue(1, param: 'two')
|
68
|
+
end
|
69
|
+
|
70
|
+
it { expect(Resque.peek(:test, 0, 100).size).to eq(2) }
|
71
|
+
end
|
63
72
|
|
64
|
-
|
73
|
+
context 'when enqueues two jobs after expire lock timeout' do
|
74
|
+
before do
|
65
75
|
UniqueJob.enqueue(1, param: 'one')
|
66
76
|
|
67
|
-
|
77
|
+
travel_redis.call(4.days)
|
78
|
+
|
79
|
+
UniqueJob.enqueue(1, param: 'one')
|
68
80
|
end
|
81
|
+
|
82
|
+
it { expect(Resque.peek(:test, 0, 100).size).to eq(2) }
|
69
83
|
end
|
70
84
|
|
71
85
|
describe 'unlock' do
|
@@ -102,4 +116,35 @@ RSpec.describe Resque::Integration do
|
|
102
116
|
end
|
103
117
|
end
|
104
118
|
end
|
119
|
+
|
120
|
+
describe 'retries' do
|
121
|
+
context 'with default params' do
|
122
|
+
let(:job) { Resque::Job.new(:test_retries, 'class' => 'RetriesJob', 'args' => ['meta']) }
|
123
|
+
|
124
|
+
it do
|
125
|
+
expect { job.perform }.to raise_error StandardError
|
126
|
+
expect(Resque.delayed_queue_schedule_size).to eq 1
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'with custom params' do
|
131
|
+
context 'with StandardError in exceptions' do
|
132
|
+
let(:job) { Resque::Job.new(:test_retries, 'class' => 'RetriesStandardErrorJob', 'args' => ['meta']) }
|
133
|
+
|
134
|
+
it do
|
135
|
+
expect { job.perform }.to raise_error StandardError
|
136
|
+
expect(Resque.delayed_queue_schedule_size).to eq 1
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'with ArgumentError in exceptions' do
|
141
|
+
let(:job) { Resque::Job.new(:test_retries, 'class' => 'RetriesArgumentErrorJob', 'args' => ['meta']) }
|
142
|
+
|
143
|
+
it do
|
144
|
+
expect { job.perform }.to raise_error StandardError
|
145
|
+
expect(Resque.delayed_queue_schedule_size).to eq 0
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
105
150
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,12 +4,13 @@ require 'rspec'
|
|
4
4
|
require 'rspec/its'
|
5
5
|
require 'resque'
|
6
6
|
require 'simplecov'
|
7
|
-
require 'mock_redis'
|
8
7
|
require 'timecop'
|
9
8
|
require 'pry-byebug'
|
10
9
|
require 'combustion'
|
11
10
|
|
12
|
-
|
11
|
+
redis = Redis.new(host: ENV['TEST_REDIS_HOST'])
|
12
|
+
Redis.current = redis
|
13
|
+
Resque.redis = redis
|
13
14
|
|
14
15
|
SimpleCov.start
|
15
16
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-integration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexei Mikhailov
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-08-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: resque
|
@@ -165,6 +165,20 @@ dependencies:
|
|
165
165
|
- - ">="
|
166
166
|
- !ruby/object:Gem::Version
|
167
167
|
version: '0'
|
168
|
+
- !ruby/object:Gem::Dependency
|
169
|
+
name: redis
|
170
|
+
requirement: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
type: :runtime
|
176
|
+
prerelease: false
|
177
|
+
version_requirements: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
168
182
|
- !ruby/object:Gem::Dependency
|
169
183
|
name: bundler
|
170
184
|
requirement: !ruby/object:Gem::Requirement
|
@@ -249,20 +263,6 @@ dependencies:
|
|
249
263
|
- - ">="
|
250
264
|
- !ruby/object:Gem::Version
|
251
265
|
version: 0.5.5
|
252
|
-
- !ruby/object:Gem::Dependency
|
253
|
-
name: mock_redis
|
254
|
-
requirement: !ruby/object:Gem::Requirement
|
255
|
-
requirements:
|
256
|
-
- - ">="
|
257
|
-
- !ruby/object:Gem::Version
|
258
|
-
version: '0'
|
259
|
-
type: :development
|
260
|
-
prerelease: false
|
261
|
-
version_requirements: !ruby/object:Gem::Requirement
|
262
|
-
requirements:
|
263
|
-
- - ">="
|
264
|
-
- !ruby/object:Gem::Version
|
265
|
-
version: '0'
|
266
266
|
- !ruby/object:Gem::Dependency
|
267
267
|
name: timecop
|
268
268
|
requirement: !ruby/object:Gem::Requirement
|
@@ -349,6 +349,10 @@ files:
|
|
349
349
|
- lib/resque/integration/version.rb
|
350
350
|
- resque-integration.gemspec
|
351
351
|
- spec/fixtures/resque_queues.yml
|
352
|
+
- spec/internal/app/jobs/retries_argument_error_job.rb
|
353
|
+
- spec/internal/app/jobs/retries_job.rb
|
354
|
+
- spec/internal/app/jobs/retries_standard_error_job.rb
|
355
|
+
- spec/internal/app/services/dummy_for_retries_service.rb
|
352
356
|
- spec/resque/controllers/jobs_controller_spec.rb
|
353
357
|
- spec/resque/integration/configuration_spec.rb
|
354
358
|
- spec/resque/integration/continuous_spec.rb
|
@@ -389,6 +393,10 @@ specification_version: 4
|
|
389
393
|
summary: Seamless integration of resque with resque-progress and resque-lock
|
390
394
|
test_files:
|
391
395
|
- spec/fixtures/resque_queues.yml
|
396
|
+
- spec/internal/app/jobs/retries_argument_error_job.rb
|
397
|
+
- spec/internal/app/jobs/retries_job.rb
|
398
|
+
- spec/internal/app/jobs/retries_standard_error_job.rb
|
399
|
+
- spec/internal/app/services/dummy_for_retries_service.rb
|
392
400
|
- spec/resque/controllers/jobs_controller_spec.rb
|
393
401
|
- spec/resque/integration/configuration_spec.rb
|
394
402
|
- spec/resque/integration/continuous_spec.rb
|