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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d09663fd4ebbbdeab2821981399c99d590c4d1f4
4
- data.tar.gz: ae7c8f47a7b88af93bf6e5e46577f4e95ae8bcac
3
+ metadata.gz: d37c0511fee9c3f766f352cb18ef36c4980cc869
4
+ data.tar.gz: d8dd5259944ac4ed274530171bda477551bb9f09
5
5
  SHA512:
6
- metadata.gz: f3029f15b7082a53034862bdb3d0b9aae77784ac95f9dc73c05966abd881d722a7e5285ea8e83f28697a77f8d2dc6266d8c89e82e25b5d65a4c7564d3e105fcf
7
- data.tar.gz: 2aebb5a7298e3bb1713f0490e4062445d74f600b657d47e77d27b06d64dfbd34a0e90ca3aa481c4eefb2169fb62f86dd4567835249f2737de02fcbcb328d526b
6
+ metadata.gz: '09ee9d7d3640eb5138138bc941064adcb19cb0ef817d90048613c2cb9c1bb01546ea428b6f10f5ab13b0a874b6289a7ae1ecaead8b36a8fd443c4cba16decf77'
7
+ data.tar.gz: 5bdbe905a197ac686192ca05b192a3e64808a0c676498366b3c18ca7cd8ec4a638d0576aab0f7c77ab7eeb0f72a54698d83d46bf2c68e3324fa23410235d5600
data/.drone.yml CHANGED
@@ -1,28 +1,74 @@
1
- build:
2
- test:
3
- image: abakpress/dind-testing
4
- pull: true
5
- privileged: true
6
- volumes:
7
- - /home/data/drone/images:/images
8
- - /home/data/drone/gems:/bundle
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
- - COMPOSE_FILE_EXT=drone
11
- - RUBY_IMAGE_TAG=2.2-latest
12
- commands:
13
- - wrapdocker docker -v
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
- - fetch-images --image abakpress/ruby-app:$RUBY_IMAGE_TAG
16
- - dip provision
17
- - dip rspec
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: true
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
- - /home/data/drone/rubygems:/root/.gem
71
+ - name: rubygems
72
+ path: /root/.gem
27
73
  commands:
28
74
  - release-gem --public
data/Appraisals CHANGED
@@ -1,13 +1,7 @@
1
- appraise 'rails3.2' do
2
- gem 'rails', '~> 3.2.0'
3
- end
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.4.1
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
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in resque-integration.gemspec
4
4
  gemspec
5
+
6
+ gem 'pry', '< 0.13.0', require: false
data/dip.yml CHANGED
@@ -1,8 +1,9 @@
1
1
  version: '1'
2
2
 
3
3
  environment:
4
- DOCKER_RUBY_VERSION: '2.2'
5
- RUBY_IMAGE_TAG: 2.2-latest
4
+ DOCKER_RUBY_VERSION: 2.3
5
+ RUBY_IMAGE_TAG: 2.3-latest
6
+ REDIS_IMAGE_TAG: 4-alpine
6
7
  COMPOSE_FILE_EXT: development
7
8
  RAILS_ENV: test
8
9
  APRESS_GEMS_CREDENTIALS: ""
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'
@@ -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
- # :limit - Integer (default: 2)
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)
@@ -35,7 +35,7 @@ module Resque::Integration
35
35
  initializer 'resque-integration.redis' do
36
36
  redis = Resque.config.redis
37
37
 
38
- if redis.any?
38
+ if redis.present?
39
39
  Resque.redis = Redis.new(redis)
40
40
  Resque.redis.namespace = redis[:namespace] if redis[:namespace]
41
41
  end
@@ -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
- Resque.redis.client.disconnect
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
- Resque.redis.client.connect
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} restart resque`
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.exists(lock_id(*args))
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
@@ -1,5 +1,5 @@
1
1
  module Resque
2
2
  module Integration
3
- VERSION = '3.4.1'.freeze
3
+ VERSION = '3.8.0'.freeze
4
4
  end
5
5
  end
@@ -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
@@ -0,0 +1,10 @@
1
+ class RetriesArgumentErrorJob
2
+ include Resque::Integration
3
+
4
+ retries temporary: true, exceptions: [ArgumentError]
5
+ queue :test_retries
6
+
7
+ def self.execute
8
+ DummyForRetriesService.call
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ class RetriesJob
2
+ include Resque::Integration
3
+
4
+ retries
5
+ queue :test_retries
6
+
7
+ def self.execute
8
+ DummyForRetriesService.call
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ class RetriesStandardErrorJob
2
+ include Resque::Integration
3
+
4
+ retries temporary: true, exceptions: [StandardError]
5
+ queue :test_retries
6
+
7
+ def self.execute
8
+ DummyForRetriesService.call
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class DummyForRetriesService
2
+ def self.call
3
+ raise StandardError.new('test')
4
+ end
5
+ 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
- it 'enqueues only one job' do
42
- UniqueJob.enqueue(1, param: 'one')
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
- Timecop.travel(10.hours.since) do
45
- UniqueJob.enqueue(1, param: 'one')
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
- it 'enqueues two jobs with differ args' do
52
- UniqueJob.enqueue(1, param: 'one')
52
+ context 'when enqueues only one job' do
53
+ before do
54
+ UniqueJob.enqueue(1, param: 'one')
53
55
 
54
- Timecop.travel(10.hours.since) do
55
- UniqueJob.enqueue(1, param: 'two')
56
+ travel_redis.call(10.hours)
56
57
 
57
- expect(Resque.peek(:test, 0, 100).size).to eq(2)
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
- it 'enqueues two jobs after expire lock timeout' do
62
- UniqueJob.enqueue(1, param: 'one')
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
- Timecop.travel(4.days.since) do
73
+ context 'when enqueues two jobs after expire lock timeout' do
74
+ before do
65
75
  UniqueJob.enqueue(1, param: 'one')
66
76
 
67
- expect(Resque.peek(:test, 0, 100).size).to eq(2)
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
- Resque.redis = MockRedis.new
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.1
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: 2018-08-22 00:00:00.000000000 Z
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