fleiss 0.4.3 → 0.5.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/test.yml +2 -2
- data/.rubocop.yml +1 -1
- data/Gemfile.lock +45 -46
- data/README.md +10 -0
- data/fleiss.gemspec +3 -3
- data/lib/active_job/queue_adapters/fleiss_adapter.rb +2 -2
- data/lib/fleiss/backend/active_record/concern.rb +1 -1
- data/lib/fleiss/cli.rb +1 -1
- data/lib/fleiss/worker.rb +11 -11
- metadata +7 -16
- data/spec/fleiss/backend/active_record_spec.rb +0 -135
- data/spec/fleiss/executor_spec.rb +0 -29
- data/spec/fleiss/worker_spec.rb +0 -47
- data/spec/fleiss_spec.rb +0 -13
- data/spec/spec_helper.rb +0 -51
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 595c3a8342470029088f398a77d8ca94cbaf78ff78a26bdda6ba31e204dc776f
|
|
4
|
+
data.tar.gz: '084f59a371721136d41294463fdd5cb41f0bdf99f958ca30cbf991863c1d35c1'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 336dcf65cd04c2e3dd005aef1e5c59d11dc6c25ab01b7cfe2b627f101c992d43e554f4a97a21a7d8886e1c0c7e19e400008d746c0d1fec302fa942dcdcd04171
|
|
7
|
+
data.tar.gz: 500004b1f9825d10dce9ae1b1178e27f71898e45ab7df6376b19f542afd24444dd8913286f9b46d4a71d2eecf1ba6c843f9a286216f9a8221b9a00891f2da5c9
|
data/.github/workflows/test.yml
CHANGED
|
@@ -11,9 +11,9 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
strategy:
|
|
13
13
|
matrix:
|
|
14
|
-
ruby-version: ["2.
|
|
14
|
+
ruby-version: ["2.7", "3.0", "3.1"]
|
|
15
15
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@v3
|
|
17
17
|
- uses: ruby/setup-ruby@v1
|
|
18
18
|
with:
|
|
19
19
|
ruby-version: ${{ matrix.ruby-version }}
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
fleiss (0.
|
|
4
|
+
fleiss (0.5.0)
|
|
5
5
|
activejob (>= 6.0)
|
|
6
6
|
activerecord (>= 6.0)
|
|
7
7
|
concurrent-ruby
|
|
@@ -9,80 +9,79 @@ PATH
|
|
|
9
9
|
GEM
|
|
10
10
|
remote: https://rubygems.org/
|
|
11
11
|
specs:
|
|
12
|
-
activejob (
|
|
13
|
-
activesupport (=
|
|
12
|
+
activejob (7.0.3.1)
|
|
13
|
+
activesupport (= 7.0.3.1)
|
|
14
14
|
globalid (>= 0.3.6)
|
|
15
|
-
activemodel (
|
|
16
|
-
activesupport (=
|
|
17
|
-
activerecord (
|
|
18
|
-
activemodel (=
|
|
19
|
-
activesupport (=
|
|
20
|
-
activesupport (
|
|
15
|
+
activemodel (7.0.3.1)
|
|
16
|
+
activesupport (= 7.0.3.1)
|
|
17
|
+
activerecord (7.0.3.1)
|
|
18
|
+
activemodel (= 7.0.3.1)
|
|
19
|
+
activesupport (= 7.0.3.1)
|
|
20
|
+
activesupport (7.0.3.1)
|
|
21
21
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
22
22
|
i18n (>= 1.6, < 2)
|
|
23
23
|
minitest (>= 5.1)
|
|
24
24
|
tzinfo (~> 2.0)
|
|
25
|
-
zeitwerk (~> 2.3)
|
|
26
25
|
ast (2.4.2)
|
|
27
|
-
concurrent-ruby (1.1.
|
|
28
|
-
diff-lcs (1.
|
|
29
|
-
globalid (0.
|
|
26
|
+
concurrent-ruby (1.1.10)
|
|
27
|
+
diff-lcs (1.5.0)
|
|
28
|
+
globalid (1.0.0)
|
|
30
29
|
activesupport (>= 5.0)
|
|
31
|
-
i18n (1.
|
|
30
|
+
i18n (1.11.0)
|
|
32
31
|
concurrent-ruby (~> 1.0)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
json (2.6.2)
|
|
33
|
+
minitest (5.16.2)
|
|
34
|
+
mysql2 (0.5.4)
|
|
35
|
+
parallel (1.22.1)
|
|
36
|
+
parser (3.1.2.0)
|
|
37
37
|
ast (~> 2.4.1)
|
|
38
|
-
pg (1.
|
|
39
|
-
rainbow (3.
|
|
38
|
+
pg (1.4.1)
|
|
39
|
+
rainbow (3.1.1)
|
|
40
40
|
rake (13.0.6)
|
|
41
|
-
regexp_parser (2.
|
|
41
|
+
regexp_parser (2.5.0)
|
|
42
42
|
rexml (3.2.5)
|
|
43
|
-
rspec (3.
|
|
44
|
-
rspec-core (~> 3.
|
|
45
|
-
rspec-expectations (~> 3.
|
|
46
|
-
rspec-mocks (~> 3.
|
|
47
|
-
rspec-core (3.
|
|
48
|
-
rspec-support (~> 3.
|
|
49
|
-
rspec-expectations (3.
|
|
43
|
+
rspec (3.11.0)
|
|
44
|
+
rspec-core (~> 3.11.0)
|
|
45
|
+
rspec-expectations (~> 3.11.0)
|
|
46
|
+
rspec-mocks (~> 3.11.0)
|
|
47
|
+
rspec-core (3.11.0)
|
|
48
|
+
rspec-support (~> 3.11.0)
|
|
49
|
+
rspec-expectations (3.11.0)
|
|
50
50
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
51
|
-
rspec-support (~> 3.
|
|
52
|
-
rspec-mocks (3.
|
|
51
|
+
rspec-support (~> 3.11.0)
|
|
52
|
+
rspec-mocks (3.11.1)
|
|
53
53
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
54
|
-
rspec-support (~> 3.
|
|
55
|
-
rspec-support (3.
|
|
56
|
-
rubocop (1.
|
|
54
|
+
rspec-support (~> 3.11.0)
|
|
55
|
+
rspec-support (3.11.0)
|
|
56
|
+
rubocop (1.31.2)
|
|
57
|
+
json (~> 2.3)
|
|
57
58
|
parallel (~> 1.10)
|
|
58
|
-
parser (>= 3.
|
|
59
|
+
parser (>= 3.1.0.0)
|
|
59
60
|
rainbow (>= 2.2.2, < 4.0)
|
|
60
61
|
regexp_parser (>= 1.8, < 3.0)
|
|
61
|
-
rexml
|
|
62
|
-
rubocop-ast (>= 1.
|
|
62
|
+
rexml (>= 3.2.5, < 4.0)
|
|
63
|
+
rubocop-ast (>= 1.18.0, < 2.0)
|
|
63
64
|
ruby-progressbar (~> 1.7)
|
|
64
65
|
unicode-display_width (>= 1.4.0, < 3.0)
|
|
65
|
-
rubocop-ast (1.
|
|
66
|
-
parser (>= 3.
|
|
66
|
+
rubocop-ast (1.19.1)
|
|
67
|
+
parser (>= 3.1.1.0)
|
|
67
68
|
rubocop-bsm (0.6.0)
|
|
68
69
|
rubocop (~> 1.0)
|
|
69
70
|
rubocop-performance
|
|
70
71
|
rubocop-rake
|
|
71
72
|
rubocop-rspec
|
|
72
|
-
rubocop-performance (1.
|
|
73
|
+
rubocop-performance (1.14.2)
|
|
73
74
|
rubocop (>= 1.7.0, < 2.0)
|
|
74
75
|
rubocop-ast (>= 0.4.0)
|
|
75
76
|
rubocop-rake (0.6.0)
|
|
76
77
|
rubocop (~> 1.0)
|
|
77
|
-
rubocop-rspec (2.
|
|
78
|
-
rubocop (~> 1.
|
|
79
|
-
rubocop-ast (>= 1.1.0)
|
|
78
|
+
rubocop-rspec (2.12.1)
|
|
79
|
+
rubocop (~> 1.31)
|
|
80
80
|
ruby-progressbar (1.11.0)
|
|
81
|
-
sqlite3 (1.4.
|
|
81
|
+
sqlite3 (1.4.4)
|
|
82
82
|
tzinfo (2.0.4)
|
|
83
83
|
concurrent-ruby (~> 1.0)
|
|
84
|
-
unicode-display_width (2.
|
|
85
|
-
zeitwerk (2.4.2)
|
|
84
|
+
unicode-display_width (2.2.0)
|
|
86
85
|
|
|
87
86
|
PLATFORMS
|
|
88
87
|
ruby
|
|
@@ -98,4 +97,4 @@ DEPENDENCIES
|
|
|
98
97
|
sqlite3
|
|
99
98
|
|
|
100
99
|
BUNDLED WITH
|
|
101
|
-
2.
|
|
100
|
+
2.3.16
|
data/README.md
CHANGED
|
@@ -38,6 +38,16 @@ class ExpringJob < ActiveJob::Base
|
|
|
38
38
|
end
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
Allow to subscribe on worker perform method and detect errors
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
ActiveSupport::Notifications.subscribe('worker_perform.fleiss') do |event|
|
|
45
|
+
break unless event.payload.key?(:exception_object)
|
|
46
|
+
|
|
47
|
+
Raven.capture_exception(event.payload[:exception_object])
|
|
48
|
+
end
|
|
49
|
+
```
|
|
50
|
+
|
|
41
51
|
Include the data migration:
|
|
42
52
|
|
|
43
53
|
```ruby
|
data/fleiss.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'fleiss'
|
|
3
|
-
s.version = '0.
|
|
3
|
+
s.version = '0.5.0'
|
|
4
4
|
s.authors = ['Black Square Media Ltd']
|
|
5
5
|
s.email = ['info@blacksquaremedia.com']
|
|
6
6
|
s.summary = %(Minimialist background jobs backed by ActiveJob and ActiveRecord.)
|
|
@@ -10,9 +10,8 @@ Gem::Specification.new do |s|
|
|
|
10
10
|
|
|
11
11
|
s.executables = ['fleiss']
|
|
12
12
|
s.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^spec/}) }
|
|
13
|
-
s.test_files = `git ls-files -z -- spec/*`.split("\x0")
|
|
14
13
|
s.require_paths = ['lib']
|
|
15
|
-
s.required_ruby_version = '>= 2.
|
|
14
|
+
s.required_ruby_version = '>= 2.7'
|
|
16
15
|
|
|
17
16
|
s.add_dependency 'activejob', '>= 6.0'
|
|
18
17
|
s.add_dependency 'activerecord', '>= 6.0'
|
|
@@ -25,4 +24,5 @@ Gem::Specification.new do |s|
|
|
|
25
24
|
s.add_development_dependency 'rspec'
|
|
26
25
|
s.add_development_dependency 'rubocop-bsm'
|
|
27
26
|
s.add_development_dependency 'sqlite3'
|
|
27
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
|
28
28
|
end
|
|
@@ -3,11 +3,11 @@ require 'fleiss'
|
|
|
3
3
|
module ActiveJob
|
|
4
4
|
module QueueAdapters
|
|
5
5
|
class FleissAdapter
|
|
6
|
-
def enqueue(job)
|
|
6
|
+
def enqueue(job) # :nodoc:
|
|
7
7
|
enqueue_at(job, nil)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def enqueue_at(job, scheduled_at)
|
|
10
|
+
def enqueue_at(job, scheduled_at) # :nodoc:
|
|
11
11
|
job_id = Fleiss.backend.enqueue(job, scheduled_at: scheduled_at)
|
|
12
12
|
job.provider_job_id = job_id
|
|
13
13
|
job_id
|
data/lib/fleiss/cli.rb
CHANGED
|
@@ -31,7 +31,7 @@ module Fleiss
|
|
|
31
31
|
return unless opts[:config]
|
|
32
32
|
|
|
33
33
|
# Load config file
|
|
34
|
-
conf = YAML.safe_load(ERB.new(
|
|
34
|
+
conf = YAML.safe_load(ERB.new(File.read(opts[:config])).result)
|
|
35
35
|
raise ArgumentError, "File in #{opts[:config]} does not contain a valid configuration" unless conf.is_a?(Hash)
|
|
36
36
|
|
|
37
37
|
conf.each do |key, value|
|
data/lib/fleiss/worker.rb
CHANGED
|
@@ -11,8 +11,6 @@ class Fleiss::Worker
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
# Init a new worker instance
|
|
14
|
-
# @param [ConnectionPool] disque client connection pool
|
|
15
|
-
# @param [Hash] options
|
|
16
14
|
# @option [Array<String>] :queues queues to watch. Default: ["default"]
|
|
17
15
|
# @option [Integer] :concurrency the number of concurrent pool. Default: 10
|
|
18
16
|
# @option [Numeric] :wait_time maximum time (in seconds) to wait for jobs when retrieving next batch. Default: 1s.
|
|
@@ -62,21 +60,24 @@ class Fleiss::Worker
|
|
|
62
60
|
|
|
63
61
|
batch.each do |job|
|
|
64
62
|
@pool.post do
|
|
65
|
-
|
|
63
|
+
thread_id = Thread.current.object_id.to_s(16).reverse
|
|
64
|
+
Fleiss.backend.wrap_perform { perform(job, thread_id) }
|
|
65
|
+
rescue StandardError => e
|
|
66
|
+
log_exception e, "processing job ##{job.id} (by thread #{thread_id})"
|
|
66
67
|
end
|
|
67
68
|
end
|
|
68
69
|
rescue StandardError => e
|
|
69
|
-
|
|
70
|
+
log_exception e, 'running cycle'
|
|
70
71
|
end
|
|
71
72
|
|
|
72
|
-
def perform(job)
|
|
73
|
-
|
|
74
|
-
owner = "#{uuid}/#{thread_id}"
|
|
73
|
+
def perform(job, thread_id)
|
|
74
|
+
owner = "#{uuid}/#{thread_id}"
|
|
75
75
|
return unless job.start(owner)
|
|
76
76
|
|
|
77
77
|
log(:info) { "Worker #{uuid} execute job ##{job.id} (by thread #{thread_id})" }
|
|
78
78
|
finished = false
|
|
79
|
-
|
|
79
|
+
|
|
80
|
+
ActiveSupport::Notifications.instrument('worker_perform.fleiss', id: job.id, uuid: uuid, thread_id: thread_id) do |payload|
|
|
80
81
|
ActiveJob::Base.execute job.job_data
|
|
81
82
|
finished = true
|
|
82
83
|
rescue StandardError
|
|
@@ -84,12 +85,11 @@ class Fleiss::Worker
|
|
|
84
85
|
raise
|
|
85
86
|
ensure
|
|
86
87
|
finished ? job.finish(owner) : job.reschedule(owner)
|
|
88
|
+
payload[:finished] = finished
|
|
87
89
|
end
|
|
88
|
-
rescue StandardError => e
|
|
89
|
-
handle_exception e, "processing job ##{job.id} (by thread #{thread_id})"
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
-
def
|
|
92
|
+
def log_exception(err, intro)
|
|
93
93
|
log(:error) do
|
|
94
94
|
[
|
|
95
95
|
"Worker #{uuid} error on #{intro}:",
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fleiss
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Black Square Media Ltd
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-07-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activejob
|
|
@@ -178,15 +178,11 @@ files:
|
|
|
178
178
|
- lib/fleiss/cli.rb
|
|
179
179
|
- lib/fleiss/executor.rb
|
|
180
180
|
- lib/fleiss/worker.rb
|
|
181
|
-
- spec/fleiss/backend/active_record_spec.rb
|
|
182
|
-
- spec/fleiss/executor_spec.rb
|
|
183
|
-
- spec/fleiss/worker_spec.rb
|
|
184
|
-
- spec/fleiss_spec.rb
|
|
185
|
-
- spec/spec_helper.rb
|
|
186
181
|
homepage: https://github.com/bsm/fleiss
|
|
187
182
|
licenses:
|
|
188
183
|
- Apache-2.0
|
|
189
|
-
metadata:
|
|
184
|
+
metadata:
|
|
185
|
+
rubygems_mfa_required: 'true'
|
|
190
186
|
post_install_message:
|
|
191
187
|
rdoc_options: []
|
|
192
188
|
require_paths:
|
|
@@ -195,20 +191,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
195
191
|
requirements:
|
|
196
192
|
- - ">="
|
|
197
193
|
- !ruby/object:Gem::Version
|
|
198
|
-
version: '2.
|
|
194
|
+
version: '2.7'
|
|
199
195
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
196
|
requirements:
|
|
201
197
|
- - ">="
|
|
202
198
|
- !ruby/object:Gem::Version
|
|
203
199
|
version: '0'
|
|
204
200
|
requirements: []
|
|
205
|
-
rubygems_version: 3.
|
|
201
|
+
rubygems_version: 3.3.7
|
|
206
202
|
signing_key:
|
|
207
203
|
specification_version: 4
|
|
208
204
|
summary: Minimialist background jobs backed by ActiveJob and ActiveRecord.
|
|
209
|
-
test_files:
|
|
210
|
-
- spec/fleiss/backend/active_record_spec.rb
|
|
211
|
-
- spec/fleiss/executor_spec.rb
|
|
212
|
-
- spec/fleiss/worker_spec.rb
|
|
213
|
-
- spec/fleiss_spec.rb
|
|
214
|
-
- spec/spec_helper.rb
|
|
205
|
+
test_files: []
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
RSpec.describe Fleiss::Backend::ActiveRecord do
|
|
4
|
-
def retrieve(job)
|
|
5
|
-
described_class.find(job.provider_job_id)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
it 'persists jobs' do
|
|
9
|
-
job = TestJob.perform_later
|
|
10
|
-
rec = retrieve(job)
|
|
11
|
-
|
|
12
|
-
expect(rec.attributes).to include(
|
|
13
|
-
'queue_name' => 'test-queue',
|
|
14
|
-
'owner' => nil,
|
|
15
|
-
'started_at' => nil,
|
|
16
|
-
'finished_at' => nil,
|
|
17
|
-
)
|
|
18
|
-
expect(rec.scheduled_at).to be_within(2.seconds).of(Time.zone.now)
|
|
19
|
-
expect(rec.expires_at).to be_within(2.seconds).of(3.days.from_now)
|
|
20
|
-
expect(rec.job_data).to include(
|
|
21
|
-
'job_class' => 'TestJob',
|
|
22
|
-
'arguments' => [],
|
|
23
|
-
'executions' => 0,
|
|
24
|
-
'locale' => 'en',
|
|
25
|
-
'priority' => nil,
|
|
26
|
-
'provider_job_id' => nil,
|
|
27
|
-
'queue_name' => 'test-queue',
|
|
28
|
-
)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it 'enqueues with delay' do
|
|
32
|
-
job = TestJob.set(wait: 1.day).perform_later
|
|
33
|
-
rec = retrieve(job)
|
|
34
|
-
expect(rec.scheduled_at).to be_within(2.seconds).of(1.day.from_now)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it 'enqueues with priority' do
|
|
38
|
-
job = TestJob.set(priority: 8).perform_later
|
|
39
|
-
rec = retrieve(job)
|
|
40
|
-
expect(rec.priority).to eq(8)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it 'exposes active job ID' do
|
|
44
|
-
job = TestJob.perform_later
|
|
45
|
-
rec = retrieve(job)
|
|
46
|
-
expect(rec.job_id.size).to eq(36)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it 'scopes pending' do
|
|
50
|
-
j1 = TestJob.perform_later
|
|
51
|
-
expect(retrieve(j1).start('owner')).to be_truthy
|
|
52
|
-
expect(retrieve(j1).finish('owner')).to be_truthy
|
|
53
|
-
|
|
54
|
-
j2 = TestJob.perform_later
|
|
55
|
-
_j3 = TestJob.set(wait: 1.hour).perform_later
|
|
56
|
-
j4 = TestJob.set(priority: 2).perform_later
|
|
57
|
-
|
|
58
|
-
expect(described_class.pending.ids).to eq [j4.provider_job_id, j2.provider_job_id]
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it 'scopes in_progress' do
|
|
62
|
-
_j1 = TestJob.perform_later
|
|
63
|
-
j2 = TestJob.perform_later
|
|
64
|
-
expect(retrieve(j2).start('owner')).to be_truthy
|
|
65
|
-
|
|
66
|
-
j3 = TestJob.perform_later
|
|
67
|
-
expect(retrieve(j3).start('owner')).to be_truthy
|
|
68
|
-
expect(described_class.in_progress('owner').ids).to match_array [j2.provider_job_id, j3.provider_job_id]
|
|
69
|
-
expect(described_class.in_progress('other').ids).to be_empty
|
|
70
|
-
|
|
71
|
-
expect(retrieve(j3).finish('owner')).to be_truthy
|
|
72
|
-
expect(described_class.in_progress('owner').ids).to eq [j2.provider_job_id]
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it 'scopes by queue' do
|
|
76
|
-
j1 = TestJob.perform_later
|
|
77
|
-
j2 = TestJob.set(queue: 'other').perform_later
|
|
78
|
-
expect(described_class.in_queue('test-queue').ids).to eq [j1.provider_job_id]
|
|
79
|
-
expect(described_class.in_queue('other').ids).to eq [j2.provider_job_id]
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
it 'starts' do
|
|
83
|
-
job = TestJob.perform_later
|
|
84
|
-
rec = retrieve(job)
|
|
85
|
-
expect(rec.start('owner')).to be_truthy
|
|
86
|
-
expect(rec.start('other')).to be_falsey
|
|
87
|
-
expect(rec.reload.owner).to eq('owner')
|
|
88
|
-
expect(rec.started_at).to be_within(2.seconds).of(Time.zone.now)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it 'locks atomically' do
|
|
92
|
-
24.times do
|
|
93
|
-
TestJob.perform_later
|
|
94
|
-
end
|
|
95
|
-
counts = (1..4).map do |n|
|
|
96
|
-
Thread.new do
|
|
97
|
-
described_class.pending.to_a.count {|j| j.start "owner-#{n}" }
|
|
98
|
-
end
|
|
99
|
-
end.map(&:value)
|
|
100
|
-
expect(counts.sum).to eq(24)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
it 'finishes' do
|
|
104
|
-
job = TestJob.perform_later
|
|
105
|
-
rec = retrieve(job)
|
|
106
|
-
expect(rec.finish('owner')).to be_falsey
|
|
107
|
-
expect(rec.start('owner')).to be_truthy
|
|
108
|
-
expect(rec.finish('other')).to be_falsey
|
|
109
|
-
expect(rec.finish('owner')).to be_truthy
|
|
110
|
-
expect(rec.reload.owner).to eq('owner')
|
|
111
|
-
expect(rec.started_at).to be_within(2.seconds).of(Time.zone.now)
|
|
112
|
-
expect(rec.finished_at).to be_within(2.seconds).of(Time.zone.now)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
it 'reschedules' do
|
|
116
|
-
job = TestJob.perform_later
|
|
117
|
-
rec = retrieve(job)
|
|
118
|
-
expect(rec.reschedule('owner')).to be_falsey
|
|
119
|
-
expect(rec.start('owner')).to be_truthy
|
|
120
|
-
expect(rec.reschedule('other')).to be_falsey
|
|
121
|
-
expect(rec.reschedule('owner')).to be_truthy
|
|
122
|
-
expect(rec.reload.owner).to be_nil
|
|
123
|
-
expect(rec.started_at).to be_nil
|
|
124
|
-
expect(rec.scheduled_at).to be_within(2.seconds).of(Time.zone.now)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
it 'reconnects' do
|
|
128
|
-
expect(::ActiveRecord::Base).to receive(:clear_active_connections!).once.and_return(nil)
|
|
129
|
-
|
|
130
|
-
expect do
|
|
131
|
-
described_class.wrap_perform { raise ::ActiveRecord::StatementInvalid }
|
|
132
|
-
end
|
|
133
|
-
.to raise_error(::ActiveRecord::StatementInvalid) # re-raised anyway
|
|
134
|
-
end
|
|
135
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'fleiss/executor'
|
|
3
|
-
|
|
4
|
-
RSpec.describe Fleiss::Executor do
|
|
5
|
-
subject { described_class.new max_size: 2 }
|
|
6
|
-
|
|
7
|
-
after { subject.kill }
|
|
8
|
-
|
|
9
|
-
it 'checks capacity' do
|
|
10
|
-
expect(described_class.new.capacity).to eq(1)
|
|
11
|
-
|
|
12
|
-
expect(subject.capacity).to eq(2)
|
|
13
|
-
subject.post { sleep(1) }
|
|
14
|
-
expect(subject.capacity).to eq(1)
|
|
15
|
-
subject.post { sleep(1) }
|
|
16
|
-
expect(subject.capacity).to eq(0)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it 'discards execution when capacity is reached' do
|
|
20
|
-
n = Concurrent::AtomicFixnum.new(0)
|
|
21
|
-
10.times do
|
|
22
|
-
10.times { subject.post { n.increment } }
|
|
23
|
-
sleep(0.001)
|
|
24
|
-
end
|
|
25
|
-
subject.shutdown
|
|
26
|
-
subject.wait_for_termination(1)
|
|
27
|
-
expect(n.value).to be_within(10).of(20)
|
|
28
|
-
end
|
|
29
|
-
end
|
data/spec/fleiss/worker_spec.rb
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'fleiss/worker'
|
|
3
|
-
|
|
4
|
-
RSpec.describe Fleiss::Worker do
|
|
5
|
-
subject do
|
|
6
|
-
described_class.new queues: TestJob.queue_name, wait_time: 0.01
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
let! :runner do
|
|
10
|
-
t = Thread.new { subject.run }
|
|
11
|
-
t.abort_on_exception = true
|
|
12
|
-
t
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
after do
|
|
16
|
-
runner.kill
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def wait_for
|
|
20
|
-
100.times do
|
|
21
|
-
break if yield
|
|
22
|
-
|
|
23
|
-
sleep(0.1)
|
|
24
|
-
end
|
|
25
|
-
expect(yield).to be_truthy
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it 'runs' do
|
|
29
|
-
# seed 24 jobs
|
|
30
|
-
24.times {|n| TestJob.perform_later(n) }
|
|
31
|
-
wait_for { Fleiss.backend.not_finished.count.positive? }
|
|
32
|
-
|
|
33
|
-
# ensure runner processes them all
|
|
34
|
-
wait_for { Fleiss.backend.not_finished.count.zero? }
|
|
35
|
-
|
|
36
|
-
# check what's been performed
|
|
37
|
-
expect(TestJob.performed.size).to eq(24)
|
|
38
|
-
expect(Fleiss.backend.finished.count).to eq(24)
|
|
39
|
-
expect(TestJob.performed).to match_array(0..23)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it 'handles failing jobs' do
|
|
43
|
-
TestJob.perform_later('raise')
|
|
44
|
-
wait_for { Fleiss.backend.not_finished.count.zero? }
|
|
45
|
-
expect(Fleiss.backend.finished.count).to eq(1)
|
|
46
|
-
end
|
|
47
|
-
end
|
data/spec/fleiss_spec.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
RSpec.describe Fleiss do
|
|
4
|
-
it 'has a backend' do
|
|
5
|
-
expect(described_class.backend).to eq(Fleiss::Backend::ActiveRecord)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
it 'enqueues' do
|
|
9
|
-
expect do
|
|
10
|
-
TestJob.set(wait: 1.week).perform_later
|
|
11
|
-
end.to change { described_class.backend.count }.by(1)
|
|
12
|
-
end
|
|
13
|
-
end
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
ENV['RACK_ENV'] ||= 'test'
|
|
2
|
-
|
|
3
|
-
require 'rspec'
|
|
4
|
-
require 'fleiss'
|
|
5
|
-
require 'fleiss/backend/active_record/migration'
|
|
6
|
-
require 'active_job'
|
|
7
|
-
require 'active_job/queue_adapters/fleiss_adapter'
|
|
8
|
-
require 'fileutils'
|
|
9
|
-
|
|
10
|
-
ActiveJob::Base.queue_adapter = :fleiss
|
|
11
|
-
ActiveJob::Base.logger = Logger.new(nil)
|
|
12
|
-
|
|
13
|
-
Time.zone_default = Time.find_zone!('UTC')
|
|
14
|
-
|
|
15
|
-
tmpdir = File.expand_path('./tmp', __dir__)
|
|
16
|
-
FileUtils.rm_rf tmpdir
|
|
17
|
-
FileUtils.mkdir_p tmpdir
|
|
18
|
-
|
|
19
|
-
database_url = ENV['DATABASE_URL'] || "sqlite3://#{tmpdir}/fleiss-test.sqlite3"
|
|
20
|
-
ActiveRecord::Base.configurations = { 'test' => { 'url' => database_url, 'pool' => 20 } }
|
|
21
|
-
|
|
22
|
-
ActiveRecord::Base.establish_connection :test
|
|
23
|
-
ActiveRecord::Base.connection.drop_table('fleiss_jobs', if_exists: true)
|
|
24
|
-
ActiveRecord::Migration.suppress_messages do
|
|
25
|
-
Fleiss::Backend::ActiveRecord::Migration.migrate(:up)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
class TestJob < ActiveJob::Base
|
|
29
|
-
queue_as 'test-queue'
|
|
30
|
-
|
|
31
|
-
def self.performed
|
|
32
|
-
@performed ||= []
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def ttl
|
|
36
|
-
72.hours
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def perform(msg = nil)
|
|
40
|
-
raise 'Failing' if msg == 'raise'
|
|
41
|
-
|
|
42
|
-
self.class.performed.push(msg)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
RSpec.configure do |c|
|
|
47
|
-
c.after do
|
|
48
|
-
TestJob.performed.clear
|
|
49
|
-
Fleiss.backend.delete_all
|
|
50
|
-
end
|
|
51
|
-
end
|