jiggler 0.1.0.rc4 → 0.1.0.rc6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -200
  3. data/bin/jiggler +1 -1
  4. data/lib/jiggler/at_least_once/acknowledger.rb +43 -0
  5. data/lib/jiggler/at_least_once/fetcher.rb +93 -0
  6. data/lib/jiggler/at_most_once/acknowledger.rb +21 -0
  7. data/lib/jiggler/at_most_once/fetcher.rb +46 -0
  8. data/lib/jiggler/base_acknowledger.rb +11 -0
  9. data/lib/jiggler/base_fetcher.rb +14 -0
  10. data/lib/jiggler/cleaner.rb +14 -5
  11. data/lib/jiggler/cli.rb +3 -2
  12. data/lib/jiggler/config.rb +48 -4
  13. data/lib/jiggler/launcher.rb +9 -3
  14. data/lib/jiggler/manager.rb +26 -2
  15. data/lib/jiggler/retrier.rb +8 -10
  16. data/lib/jiggler/scheduled/enqueuer.rb +1 -1
  17. data/lib/jiggler/scheduled/poller.rb +38 -26
  18. data/lib/jiggler/scheduled/requeuer.rb +57 -0
  19. data/lib/jiggler/server.rb +7 -0
  20. data/lib/jiggler/stats/collection.rb +3 -2
  21. data/lib/jiggler/stats/monitor.rb +2 -2
  22. data/lib/jiggler/summary.rb +8 -1
  23. data/lib/jiggler/support/helper.rb +17 -3
  24. data/lib/jiggler/version.rb +1 -1
  25. data/lib/jiggler/web.rb +0 -2
  26. data/lib/jiggler/worker.rb +21 -36
  27. data/spec/examples.txt +96 -79
  28. data/spec/fixtures/config/jiggler.yml +2 -2
  29. data/spec/jiggler/at_least_once/acknowledger_spec.rb +30 -0
  30. data/spec/jiggler/at_least_once/fetcher_spec.rb +69 -0
  31. data/spec/jiggler/at_most_once/fetcher_spec.rb +33 -0
  32. data/spec/jiggler/cleaner_spec.rb +11 -1
  33. data/spec/jiggler/cli_spec.rb +5 -7
  34. data/spec/jiggler/config_spec.rb +45 -3
  35. data/spec/jiggler/core_spec.rb +2 -0
  36. data/spec/jiggler/job_spec.rb +4 -4
  37. data/spec/jiggler/launcher_spec.rb +60 -54
  38. data/spec/jiggler/manager_spec.rb +50 -41
  39. data/spec/jiggler/retrier_spec.rb +3 -1
  40. data/spec/jiggler/scheduled/requeuer_spec.rb +57 -0
  41. data/spec/jiggler/stats/monitor_spec.rb +3 -2
  42. data/spec/jiggler/summary_spec.rb +19 -5
  43. data/spec/jiggler/worker_spec.rb +11 -15
  44. data/spec/spec_helper.rb +7 -0
  45. metadata +38 -9
@@ -1,52 +1,61 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe Jiggler::Manager do
4
- let(:config) do
5
- Jiggler::Config.new(
6
- concurrency: 4,
7
- timeout: 1,
8
- server_mode: true
9
- )
10
- end
11
- let(:collection) { Jiggler::Stats::Collection.new(config) }
12
- let(:manager) { described_class.new(config, collection) }
4
+ let(:uuid) { "#{SecureRandom.hex(3)}-test" }
5
+ let(:collection) { Jiggler::Stats::Collection.new(uuid, uuid) }
13
6
 
14
- it { expect(manager.instance_variable_get(:@workers).count).to be 4 }
7
+ [:at_most_once, :at_least_once].each do |mode|
8
+ context "with #{mode} mode" do
9
+ let(:config) do
10
+ Jiggler::Config.new(
11
+ concurrency: 4,
12
+ timeout: 1,
13
+ mode: mode
14
+ )
15
+ end
16
+ let(:manager) { described_class.new(config, collection) }
15
17
 
16
- describe '#start' do
17
- it 'starts the manager' do
18
- expect(manager.instance_variable_get(:@workers)).to all(receive(:run))
19
- Async { manager.start }
20
- sleep(0.5)
21
- manager.terminate
22
- end
23
- end
18
+ it { expect(manager.instance_variable_get(:@workers).count).to be 4 }
24
19
 
25
- describe '#suspend' do
26
- it 'suspends the manager' do
27
- expect(manager.instance_variable_get(:@workers)).to all(receive(:suspend).and_call_original)
28
- task = Async do
29
- Async { manager.start }
30
- sleep(0.5)
31
- manager.suspend
32
- expect(manager.instance_variable_get(:@done)).to be true
20
+ describe '#start' do
21
+ it 'starts the manager' do
22
+ expect(manager.instance_variable_get(:@workers)).to all(receive(:run))
23
+ task = Async do
24
+ Async { manager.start }
25
+ sleep(0.5)
26
+ manager.terminate
27
+ end
28
+ task.wait
29
+ end
33
30
  end
34
- task.wait
35
- end
36
- end
37
-
38
- describe '#terminate' do
39
- it 'terminates the manager' do
40
- expect(manager.instance_variable_get(:@workers)).to all(receive(:suspend).and_call_original)
41
- expect(manager.instance_variable_get(:@workers)).to all(receive(:terminate).and_call_original)
42
- task = Async do
43
- Async { manager.start }
44
- sleep(0.5)
45
- manager.terminate
46
- sleep(2) # wait for timeout
47
- expect(manager.instance_variable_get(:@done)).to be true
31
+
32
+ describe '#suspend' do
33
+ it 'suspends the manager' do
34
+ expect(manager.instance_variable_get(:@fetcher)).to receive(:suspend).and_call_original
35
+ task = Async do
36
+ Async { manager.start }
37
+ sleep(0.5)
38
+ manager.suspend
39
+ expect(manager.instance_variable_get(:@done)).to be true
40
+ manager.terminate
41
+ end
42
+ task.wait
43
+ end
44
+ end
45
+
46
+ describe '#terminate' do
47
+ it 'terminates the manager' do
48
+ expect(manager.instance_variable_get(:@fetcher)).to receive(:suspend).and_call_original
49
+ task = Async do
50
+ Async { manager.start }
51
+ sleep(0.5)
52
+ manager.terminate
53
+ sleep(2) # wait for timeout
54
+ expect(manager.instance_variable_get(:@done)).to be true
55
+ end
56
+ task.wait
57
+ end
48
58
  end
49
- task.wait
50
59
  end
51
60
  end
52
61
  end
@@ -8,7 +8,9 @@ RSpec.describe Jiggler::Retrier do
8
8
  queues: ['test']
9
9
  )
10
10
  end
11
- let(:collection) { Jiggler::Stats::Collection.new('test-retrier-uuid') }
11
+ let(:uuid) { "#{SecureRandom.hex(3)}-test" }
12
+ let(:identity) { "#{uuid}-identity" }
13
+ let(:collection) { Jiggler::Stats::Collection.new(uuid, identity) }
12
14
  let(:retrier) { Jiggler::Retrier.new(config, collection) }
13
15
 
14
16
  describe '#wrapped' do
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Jiggler::Scheduled::Requeuer do
4
+ let(:config) do
5
+ Jiggler::Config.new(
6
+ concurrency: 1,
7
+ timeout: 1,
8
+ poller_enabled: false,
9
+ queues: ['my_queue']
10
+ )
11
+ end
12
+ let(:launcher) { Jiggler::Launcher.new(config) }
13
+ let(:identity) { launcher.send(:identity) }
14
+ let(:uuid) { launcher.send(:uuid) }
15
+ let(:requeuer) { Jiggler::Scheduled::Requeuer.new(config) }
16
+
17
+ after { config.cleaner.prune_all }
18
+
19
+ describe '#running_processes_uuid' do
20
+ it 'fetches process uuids' do
21
+ config.with_sync_redis do |conn|
22
+ conn.call('SET', identity, 'test')
23
+ end
24
+ expect(requeuer.send(:running_processes_uuid)).to eq([uuid])
25
+ end
26
+ end
27
+
28
+ describe '#requeue_data' do
29
+ it 'selects data without running processes' do
30
+ config.with_sync_redis do |conn|
31
+ conn.call('SET', identity, 'test')
32
+ conn.call('LPUSH', "jiggler:list:my_queue:in_progress:#{uuid}", 'test')
33
+ end
34
+ expect(requeuer.send(:requeue_data)).to eq([])
35
+ config.with_sync_redis do |conn|
36
+ conn.call('DEL', identity)
37
+ end
38
+ expect(requeuer.send(:requeue_data)).to eq([
39
+ ["jiggler:list:my_queue:in_progress:#{uuid}", "jiggler:list:my_queue", uuid]
40
+ ])
41
+ end
42
+ end
43
+
44
+ describe '#handle_stale' do
45
+ it 'requeues stale data' do
46
+ config.with_sync_redis do |conn|
47
+ conn.call('LPUSH', "jiggler:list:my_queue:in_progress:#{uuid}", 'test')
48
+ expect(conn.call('LLEN', 'jiggler:list:my_queue')).to be 0
49
+ end
50
+ requeuer.handle_stale
51
+ config.with_sync_redis do |conn|
52
+ expect(conn.call('LLEN', "jiggler:list:my_queue:in_progress:#{uuid}")).to be 0
53
+ expect(conn.call('LLEN', 'jiggler:list:my_queue')).to be 1
54
+ end
55
+ end
56
+ end
57
+ end
@@ -8,7 +8,8 @@ RSpec.describe Jiggler::Stats::Monitor do
8
8
  )
9
9
  end
10
10
  let(:uuid) { 'monitor-test-uuid' }
11
- let(:collection) { Jiggler::Stats::Collection.new(uuid) }
11
+ let(:identity) { "#{uuid}-identity" }
12
+ let(:collection) { Jiggler::Stats::Collection.new(uuid, identity) }
12
13
  let(:monitor) { described_class.new(config, collection) }
13
14
 
14
15
  describe '#start' do
@@ -32,7 +33,7 @@ RSpec.describe Jiggler::Stats::Monitor do
32
33
  expect(monitor).to receive(:cleanup).and_call_original
33
34
  monitor.terminate
34
35
  expect(monitor.instance_variable_get(:@done)).to be true
35
- expect(config.client_redis_pool.acquire { |conn| conn.call('GET', uuid) }).to be nil
36
+ expect(config.client_redis_pool.acquire { |conn| conn.call('GET', identity) }).to be nil
36
37
  end
37
38
  task.wait
38
39
  end
@@ -8,10 +8,14 @@ RSpec.describe Jiggler::Summary do
8
8
  timeout: 1,
9
9
  stats_interval: 1,
10
10
  queues: queues,
11
- poller_enabled: false
11
+ poller_enabled: false,
12
+ mode: :at_most_once
12
13
  )
13
14
  end
14
- let(:collection) { Jiggler::Stats::Collection.new('summary-test-uuid') }
15
+ let(:uuid) { "#{SecureRandom.hex(3)}-test" }
16
+ let(:collection) { Jiggler::Stats::Collection.new(uuid, uuid) }
17
+ let(:acknowledger) { Jiggler::AtMostOnce::Acknowledger.new(config) }
18
+ let(:fetcher) { Jiggler::AtMostOnce::Fetcher.new(config, collection) }
15
19
  let(:summary) { described_class.new(config) }
16
20
 
17
21
  describe '.all' do
@@ -33,7 +37,7 @@ RSpec.describe Jiggler::Summary do
33
37
  Sync do
34
38
  config.cleaner.prune_all
35
39
  launcher = Jiggler::Launcher.new(config)
36
- uuid = launcher.send(:uuid)
40
+ uuid = launcher.send(:identity)
37
41
  MyJob.with_options(queue: 'queue1').enqueue
38
42
 
39
43
  first_summary = summary.all
@@ -90,12 +94,13 @@ RSpec.describe Jiggler::Summary do
90
94
 
91
95
  describe '#last_dead_jobs' do
92
96
  it 'returns last n dead jobs' do
97
+ # clean data and enqueue a failling job with no retries
93
98
  Sync do
94
99
  config.cleaner.prune_all
95
100
  expect(summary.last_dead_jobs(1)).to be_empty
96
101
  MyFailedJob.with_options(queue: 'queue1', retries: 0).enqueue('yay')
97
102
  end
98
- worker = Jiggler::Worker.new(config, collection) do
103
+ worker = Jiggler::Worker.new(config, collection, acknowledger, fetcher) do
99
104
  config.logger.info('Doing some weird dead testings')
100
105
  end
101
106
  task = Async do
@@ -106,6 +111,8 @@ RSpec.describe Jiggler::Summary do
106
111
  worker.terminate
107
112
  end
108
113
  task.wait
114
+
115
+ # ensure the job is saved as dead
109
116
  jobs = Sync { summary.last_dead_jobs(3) }
110
117
  expect(jobs.count).to be 1
111
118
  expect(jobs.first).to include({
@@ -117,6 +124,7 @@ RSpec.describe Jiggler::Summary do
117
124
 
118
125
  describe '#last_retry_jobs' do
119
126
  it 'returns last n retry jobs' do
127
+ # clean data and enqueue 5 failling jobs
120
128
  Sync do
121
129
  config.cleaner.prune_all
122
130
  expect(summary.last_retry_jobs(3)).to be_empty
@@ -127,9 +135,12 @@ RSpec.describe Jiggler::Summary do
127
135
  ).enqueue("yay-#{i}")
128
136
  end
129
137
  end
130
- worker = Jiggler::Worker.new(config, collection) do
138
+
139
+ worker = Jiggler::Worker.new(config, collection, acknowledger, fetcher) do
131
140
  config.logger.info('Doing some weird retry testings')
132
141
  end
142
+
143
+ # start worker, wait for 1 sec, terminate worker
133
144
  task = Async do
134
145
  Async do
135
146
  worker.run
@@ -138,7 +149,10 @@ RSpec.describe Jiggler::Summary do
138
149
  worker.terminate
139
150
  end
140
151
  task.wait
152
+
153
+ # fetch last 3 retry jobs to ensure they are in the right order
141
154
  jobs = Sync { summary.last_retry_jobs(3) }
155
+ puts jobs.first
142
156
  expect(jobs.count).to be 3
143
157
  expect(jobs.first).to include({
144
158
  'name' => 'MyFailedJob',
@@ -1,22 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe Jiggler::Worker do
4
- before(:all) do
4
+ before(:all) do
5
5
  Jiggler.instance_variable_set(:@config, Jiggler::Config.new(
6
6
  concurrency: 1,
7
7
  client_concurrency: 1,
8
8
  timeout: 1,
9
- queues: ['default', 'test']
10
- ) )
9
+ queues: [['default', 2], ['test', 1]],
10
+ mode: :at_most_once
11
+ ))
11
12
  end
12
13
  after(:all) do
13
14
  Jiggler.instance_variable_set(:@config, Jiggler::Config.new)
14
15
  end
15
16
 
16
17
  let(:config) { Jiggler.config }
17
- let(:collection) { Jiggler::Stats::Collection.new(config) }
18
+ let(:uuid) { "#{SecureRandom.hex(3)}-test" }
19
+ let(:collection) { Jiggler::Stats::Collection.new(uuid, uuid) }
20
+ let(:acknowledger) { Jiggler::AtMostOnce::Acknowledger.new(config) }
21
+ let(:fetcher) { Jiggler::AtMostOnce::Fetcher.new(config, collection) }
18
22
  let(:worker) do
19
- described_class.new(config, collection) do
23
+ described_class.new(config, collection, acknowledger, fetcher) do
20
24
  config.logger.debug("Callback called: #{rand(100)}")
21
25
  end
22
26
  end
@@ -90,20 +94,12 @@ RSpec.describe Jiggler::Worker do
90
94
  context 'when worker is running' do
91
95
  it 'terminates the worker' do
92
96
  task = Async do
93
- expect(worker.done).to be false
94
97
  Async { worker.run }
98
+ sleep(0.5)
95
99
  worker.terminate
96
100
  end
97
101
  task.wait
98
- expect(worker.done).to be true
99
- end
100
- end
101
-
102
- context 'when worker is not running' do
103
- it do
104
- expect(worker.done).to be false
105
- worker.terminate
106
- expect(worker.done).to be true
102
+ expect(worker.instance_variable_get(:@runner)).to be_nil
107
103
  end
108
104
  end
109
105
  end
data/spec/spec_helper.rb CHANGED
@@ -10,12 +10,19 @@ require 'jiggler/web'
10
10
  require 'jiggler/support/helper'
11
11
  require 'jiggler/scheduled/enqueuer'
12
12
  require 'jiggler/scheduled/poller'
13
+ require 'jiggler/scheduled/requeuer'
13
14
  require 'jiggler/stats/collection'
14
15
  require 'jiggler/stats/monitor'
15
16
  require 'jiggler/errors'
16
17
  require 'jiggler/retrier'
17
18
  require 'jiggler/launcher'
18
19
  require 'jiggler/manager'
20
+ require 'jiggler/base_acknowledger'
21
+ require 'jiggler/base_fetcher'
22
+ require 'jiggler/at_most_once/acknowledger'
23
+ require 'jiggler/at_most_once/fetcher'
24
+ require 'jiggler/at_least_once/acknowledger'
25
+ require 'jiggler/at_least_once/fetcher'
19
26
  require 'jiggler/worker'
20
27
  require 'jiggler/cli'
21
28
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jiggler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.rc4
4
+ version: 0.1.0.rc6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julija Alieckaja
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-01-18 00:00:00.000000000 Z
12
+ date: 2023-02-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: async
@@ -59,42 +59,56 @@ dependencies:
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '0.11'
62
+ version: '0.12'
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '0.11'
69
+ version: '0.12'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: oj
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: '3.13'
76
+ version: '3.14'
77
77
  type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: '3.13'
83
+ version: '3.14'
84
+ - !ruby/object:Gem::Dependency
85
+ name: priority_queue_cxx
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '0.3'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '0.3'
84
98
  - !ruby/object:Gem::Dependency
85
99
  name: bundler
86
100
  requirement: !ruby/object:Gem::Requirement
87
101
  requirements:
88
102
  - - "~>"
89
103
  - !ruby/object:Gem::Version
90
- version: '2.3'
104
+ version: '2.4'
91
105
  type: :development
92
106
  prerelease: false
93
107
  version_requirements: !ruby/object:Gem::Requirement
94
108
  requirements:
95
109
  - - "~>"
96
110
  - !ruby/object:Gem::Version
97
- version: '2.3'
111
+ version: '2.4'
98
112
  - !ruby/object:Gem::Dependency
99
113
  name: rake
100
114
  requirement: !ruby/object:Gem::Requirement
@@ -135,7 +149,13 @@ files:
135
149
  - README.md
136
150
  - bin/jiggler
137
151
  - lib/jiggler.rb
152
+ - lib/jiggler/at_least_once/acknowledger.rb
153
+ - lib/jiggler/at_least_once/fetcher.rb
154
+ - lib/jiggler/at_most_once/acknowledger.rb
155
+ - lib/jiggler/at_most_once/fetcher.rb
138
156
  - lib/jiggler/base.rb
157
+ - lib/jiggler/base_acknowledger.rb
158
+ - lib/jiggler/base_fetcher.rb
139
159
  - lib/jiggler/cleaner.rb
140
160
  - lib/jiggler/cli.rb
141
161
  - lib/jiggler/client.rb
@@ -149,6 +169,7 @@ files:
149
169
  - lib/jiggler/retrier.rb
150
170
  - lib/jiggler/scheduled/enqueuer.rb
151
171
  - lib/jiggler/scheduled/poller.rb
172
+ - lib/jiggler/scheduled/requeuer.rb
152
173
  - lib/jiggler/server.rb
153
174
  - lib/jiggler/stats/collection.rb
154
175
  - lib/jiggler/stats/monitor.rb
@@ -165,6 +186,9 @@ files:
165
186
  - spec/fixtures/my_failed_job.rb
166
187
  - spec/fixtures/my_job.rb
167
188
  - spec/fixtures/my_job_with_args.rb
189
+ - spec/jiggler/at_least_once/acknowledger_spec.rb
190
+ - spec/jiggler/at_least_once/fetcher_spec.rb
191
+ - spec/jiggler/at_most_once/fetcher_spec.rb
168
192
  - spec/jiggler/cleaner_spec.rb
169
193
  - spec/jiggler/cli_spec.rb
170
194
  - spec/jiggler/config_spec.rb
@@ -176,6 +200,7 @@ files:
176
200
  - spec/jiggler/retrier_spec.rb
177
201
  - spec/jiggler/scheduled/enqueuer_spec.rb
178
202
  - spec/jiggler/scheduled/poller_spec.rb
203
+ - spec/jiggler/scheduled/requeuer_spec.rb
179
204
  - spec/jiggler/stats/monitor_spec.rb
180
205
  - spec/jiggler/summary_spec.rb
181
206
  - spec/jiggler/web_spec.rb
@@ -204,7 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
229
  - !ruby/object:Gem::Version
205
230
  version: 1.3.1
206
231
  requirements: []
207
- rubygems_version: 3.4.3
232
+ rubygems_version: 3.4.6
208
233
  signing_key:
209
234
  specification_version: 4
210
235
  summary: Ruby background job processor
@@ -215,6 +240,9 @@ test_files:
215
240
  - spec/fixtures/my_failed_job.rb
216
241
  - spec/fixtures/my_job.rb
217
242
  - spec/fixtures/my_job_with_args.rb
243
+ - spec/jiggler/at_least_once/acknowledger_spec.rb
244
+ - spec/jiggler/at_least_once/fetcher_spec.rb
245
+ - spec/jiggler/at_most_once/fetcher_spec.rb
218
246
  - spec/jiggler/cleaner_spec.rb
219
247
  - spec/jiggler/cli_spec.rb
220
248
  - spec/jiggler/config_spec.rb
@@ -226,6 +254,7 @@ test_files:
226
254
  - spec/jiggler/retrier_spec.rb
227
255
  - spec/jiggler/scheduled/enqueuer_spec.rb
228
256
  - spec/jiggler/scheduled/poller_spec.rb
257
+ - spec/jiggler/scheduled/requeuer_spec.rb
229
258
  - spec/jiggler/stats/monitor_spec.rb
230
259
  - spec/jiggler/summary_spec.rb
231
260
  - spec/jiggler/web_spec.rb