fleiss 0.4.5 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a8ecda4ed800fa1d15848bf37c3f7f1a49cba62be614d25eea8725c00baab0d
4
- data.tar.gz: fade5ca7d61dad9e7a912b99125b1b43159ab61df2c68b02fb8ed21a73382854
3
+ metadata.gz: 595c3a8342470029088f398a77d8ca94cbaf78ff78a26bdda6ba31e204dc776f
4
+ data.tar.gz: '084f59a371721136d41294463fdd5cb41f0bdf99f958ca30cbf991863c1d35c1'
5
5
  SHA512:
6
- metadata.gz: ee3ee999372b9d214cd7261e115a0a5ceb7b0c3b266dc2924cb6c7f8c888fbd98140fd39a02a75e108af4f541bee564a67cef179ed62e38d4a0ae019f071f182
7
- data.tar.gz: 70d922d556feeef102242c726c1812f4f4625ee25f19d01087074aa0725b677d0e74e043097f665b9626f3e16bc5a424f5441e8a3e96088e180cabb9d1a99b45
6
+ metadata.gz: 336dcf65cd04c2e3dd005aef1e5c59d11dc6c25ab01b7cfe2b627f101c992d43e554f4a97a21a7d8886e1c0c7e19e400008d746c0d1fec302fa942dcdcd04171
7
+ data.tar.gz: 500004b1f9825d10dce9ae1b1178e27f71898e45ab7df6376b19f542afd24444dd8913286f9b46d4a71d2eecf1ba6c843f9a286216f9a8221b9a00891f2da5c9
@@ -11,9 +11,9 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
14
- ruby-version: ["2.6", "2.7", "3.0"]
14
+ ruby-version: ["2.7", "3.0", "3.1"]
15
15
  steps:
16
- - uses: actions/checkout@v2
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
@@ -5,7 +5,7 @@ inherit_mode:
5
5
  merge:
6
6
  - Exclude
7
7
  AllCops:
8
- TargetRubyVersion: "2.6"
8
+ TargetRubyVersion: "2.7"
9
9
 
10
10
  Security/Open:
11
11
  Exclude:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fleiss (0.4.5)
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 (6.1.4.1)
13
- activesupport (= 6.1.4.1)
12
+ activejob (7.0.3.1)
13
+ activesupport (= 7.0.3.1)
14
14
  globalid (>= 0.3.6)
15
- activemodel (6.1.4.1)
16
- activesupport (= 6.1.4.1)
17
- activerecord (6.1.4.1)
18
- activemodel (= 6.1.4.1)
19
- activesupport (= 6.1.4.1)
20
- activesupport (6.1.4.1)
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.9)
28
- diff-lcs (1.4.4)
29
- globalid (0.5.2)
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.8.10)
30
+ i18n (1.11.0)
32
31
  concurrent-ruby (~> 1.0)
33
- minitest (5.14.4)
34
- mysql2 (0.5.3)
35
- parallel (1.21.0)
36
- parser (3.0.2.0)
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.2.3)
39
- rainbow (3.0.0)
38
+ pg (1.4.1)
39
+ rainbow (3.1.1)
40
40
  rake (13.0.6)
41
- regexp_parser (2.1.1)
41
+ regexp_parser (2.5.0)
42
42
  rexml (3.2.5)
43
- rspec (3.10.0)
44
- rspec-core (~> 3.10.0)
45
- rspec-expectations (~> 3.10.0)
46
- rspec-mocks (~> 3.10.0)
47
- rspec-core (3.10.1)
48
- rspec-support (~> 3.10.0)
49
- rspec-expectations (3.10.1)
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.10.0)
52
- rspec-mocks (3.10.2)
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.10.0)
55
- rspec-support (3.10.2)
56
- rubocop (1.21.0)
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.0.0.0)
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.9.1, < 2.0)
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.11.0)
66
- parser (>= 3.0.1.1)
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.11.5)
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.4.0)
78
- rubocop (~> 1.0)
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.2)
81
+ sqlite3 (1.4.4)
82
82
  tzinfo (2.0.4)
83
83
  concurrent-ruby (~> 1.0)
84
- unicode-display_width (2.1.0)
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.2.16
100
+ 2.3.16
data/fleiss.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'fleiss'
3
- s.version = '0.4.5'
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.6'
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
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(IO.read(opts[:config])).result)
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|
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.5
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: 2021-10-22 00:00:00.000000000 Z
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.6'
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.2.15
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_all_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
@@ -1,68 +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
- around do |example|
20
- callback = ->(*args) { notifications.push ActiveSupport::Notifications::Event.new(*args) }
21
- ActiveSupport::Notifications.subscribed(callback, 'worker_perform.fleiss') do
22
- example.call
23
- end
24
- end
25
-
26
- def wait_for
27
- 100.times do
28
- break if yield
29
-
30
- sleep(0.1)
31
- end
32
- expect(yield).to be_truthy
33
- end
34
-
35
- it 'runs' do
36
- # seed 24 jobs
37
- 24.times {|n| TestJob.perform_later(n) }
38
- wait_for { Fleiss.backend.not_finished.count.positive? }
39
-
40
- # ensure runner processes them all
41
- wait_for { Fleiss.backend.not_finished.count.zero? }
42
-
43
- # check what's been performed
44
- expect(TestJob.performed.size).to eq(24)
45
- expect(Fleiss.backend.finished.count).to eq(24)
46
- expect(TestJob.performed).to match_array(0..23)
47
- end
48
-
49
- it 'handles failing jobs' do
50
- TestJob.perform_later('raise')
51
- wait_for { Fleiss.backend.not_finished.count.zero? }
52
- expect(Fleiss.backend.finished.count).to eq(1)
53
-
54
- expect(notifications.size).to eq(1)
55
- expect(notifications.first.payload).to have_key(:id)
56
- expect(notifications.first.payload).to have_key(:uuid)
57
- expect(notifications.first.payload).to have_key(:thread_id)
58
- expect(notifications.first.payload[:finished]).to be_truthy
59
- expect(notifications.first.payload[:exception_object]).to be_an_instance_of(RuntimeError)
60
- expect(notifications.first.payload[:exception_object].message).to eq('Failing')
61
- end
62
-
63
- private
64
-
65
- def notifications
66
- @notifications ||= []
67
- end
68
- 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