resque-integration 3.4.1 → 3.8.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/.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
|