infopark-politics 0.8.4 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- M2Y0YWFlODFhZTgwYzc3Nzc1NTI5ZGJkNjEwOGRkNzFiMmE2YzFkOQ==
4
+ ZTc2ZjhmOTAwNTNjNTNlYWExZjAwM2Y5ZDY0ZDQ4NmViOGVmNjNkZg==
5
5
  data.tar.gz: !binary |-
6
- MzdhYzlhN2E0YzYxMmMyMjJkMWM4NTAyZTc5MWRjMzFkNDgyOWFiZg==
6
+ OGEyNjc2N2IwYjcyZjU3NDFiYWE4ZDY2N2Q4NDhjYzIxZDRlMDc1Ng==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- N2IwOTBjNjljOWNhOTI4N2I5OTY4MWNhMDI0ZjQ4ZGYyMzA3ZjM5YjAyMDJi
10
- ZDU3MTU0OTQ1YWUzOGQ5Y2ZkYmNkYTg4ZGQwZmZhNDA0NGY1MjY3ODhkZTgz
11
- MTcyYjQ4Mzk5Zjg5MDU3MzIzMDdjOWM3ZjM0NmJkYTI1MzJhOGE=
9
+ ZmQ0YjM2NzU1YzY0ZjQ3ZWZlOWY5MjE0ZDg1ZTIwMTE1ZjE4OTVjNTE5NmYw
10
+ ZWQ1ODZiOWFiOWE0NTE3M2RiZjgxYzJhMThiMDJiYzQxZjU5NTQwYWM3OTVi
11
+ MzlmYTEzODM2Yzg0ZjljMTFlNTc5NWViZTUxZmZiZDkxOGQ1OTY=
12
12
  data.tar.gz: !binary |-
13
- NDFlODU5NTVmYzE2YzRlMGFlNjdmZjAwMDY5Y2E0MGVkNTEzNzNiZTMzOTY0
14
- Y2U3ZTUzMmFjYWZiOGMyNWU2YTRkY2VkMWQ1MDc1Y2I4ZGY1MTdmNDRiMzcy
15
- NDQ2YTVhODVmNWUzMDRhMWI5NWY1ZmM2MTU3YmM5ZmQxMDg4MzM=
13
+ M2JlY2ExN2NiMmZhYWU3MjI0ZjYyMWRiMDljOWY5ZmQ5ZWRhYTBiNmZiNGRk
14
+ NzZjMTAyMmRiYTYyNGI5ZTJlODNiZjdmNjMzNzU5NjE1Zjc1NzZiYmFlYWMz
15
+ YTk0YmIzY2E1OWJlMTFlNzM2YWNmMTViMjJkNjhhN2UzNmZhMWQ=
@@ -6,7 +6,7 @@ end
6
6
 
7
7
  Gem::Specification.new do |gem|
8
8
  gem.name = "infopark-politics"
9
- gem.version = "0.8.4"
9
+ gem.version = "0.9.0"
10
10
  gem.summary = "Algorithms and Tools for Distributed Computing in Ruby."
11
11
  gem.description = ""
12
12
  gem.authors = ["Mike Perham", "Tilo Prütz"]
@@ -19,7 +19,7 @@ module Politics
19
19
 
20
20
  @group_name = name
21
21
  @iteration_length = options[:iteration_length]
22
- @memcache_client = client_for(Array(options[:servers]))
22
+ @memcache_config = Array(options[:servers])
23
23
  @dictatorship_length = options[:dictatorship_length]
24
24
 
25
25
  @buckets = []
@@ -30,7 +30,7 @@ module Politics
30
30
  log.progname = uri
31
31
  log.info { "Registered in group #{group_name} at #{uri}" }
32
32
  at_exit do
33
- internal_cleanup
33
+ internal_cleanup(client_for(memcache_config))
34
34
  cleanup
35
35
  end
36
36
  end
@@ -39,10 +39,11 @@ module Politics
39
39
  def process_bucket(&block)
40
40
  log.debug "start bucket processing"
41
41
  raise ArgumentError, "process_bucket requires a block!" unless block_given?
42
- unless memcache_client
42
+ unless memcache_config
43
43
  raise ArgumentError, "You must call register_worker before processing!"
44
44
  end
45
45
 
46
+ worker_memcache_client = client_for(memcache_config)
46
47
  begin
47
48
  begin
48
49
  raise "self is not alive via drb" unless DRbObject.new(nil, uri).alive?
@@ -50,20 +51,21 @@ module Politics
50
51
  raise "cannot reach self via drb: #{e.message}"
51
52
  end
52
53
  begin
53
- nominate
54
+ nominate(worker_memcache_client)
54
55
 
55
- if leader? && !(@leader_thread && @leader_thread.alive?)
56
+ if leader?(worker_memcache_client) && !(@leader_thread && @leader_thread.alive?)
56
57
  unless (@leader_thread && @leader_thread.alive?)
57
58
  @leader_thread = Thread.new do
58
- perform_leader_duties
59
+ leader_memcache_client = client_for(memcache_config)
60
+ perform_leader_duties(leader_memcache_client)
59
61
  end
60
62
  end
61
63
  end
62
64
 
63
65
  # Get a bucket from the leader and process it
64
66
  begin
65
- log.debug "getting bucket request from leader (#{leader_uri}) and processing it"
66
- bucket_process(*leader.bucket_request(uri, bucket_request_context), &block)
67
+ log.debug "getting bucket request from leader (#{leader_uri(worker_memcache_client)}) and processing it"
68
+ bucket_process(*leader(worker_memcache_client).bucket_request(uri, bucket_request_context), &block)
67
69
  rescue DRb::DRbError => dre
68
70
  log.error { "Error talking to leader: #{dre.message}" }
69
71
  relax until_next_iteration
@@ -75,44 +77,44 @@ module Politics
75
77
  end while loop?
76
78
  end
77
79
 
78
- def as_dictator(&block)
80
+ def as_dictator(memcache_client, &block)
79
81
  duration = dictatorship_length || (iteration_length * 10)
80
82
  log.debug { "become dictator for up to #{duration} seconds" }
81
- seize_leadership duration
83
+ seize_leadership(memcache_client, duration)
82
84
  yield
83
- raise "lost leadership while being dictator for #{duration} seconds" unless leader?
84
- seize_leadership
85
+ raise "lost leadership while being dictator for #{duration} seconds" unless leader?(memcache_client)
86
+ seize_leadership(memcache_client)
85
87
  end
86
88
 
87
- def seize_leadership(*args)
89
+ def seize_leadership(memcache_client, *args)
88
90
  start_iteration(*args) {|duration| memcache_client.set(token, uri, duration) }
89
91
  end
90
92
 
91
- def perform_leader_duties
93
+ def perform_leader_duties(memcache_client)
92
94
  with_errors_logged('leader duties') do
93
95
  # The DRb thread handles the requests to the leader.
94
96
  # This method performs the bucket managing.
95
97
  log.info { "has been elected leader" }
96
98
  before_perform_leader_duties
97
99
  # keeping leader state as long as buckets are being initialized
98
- as_dictator { initialize_buckets }
100
+ as_dictator(memcache_client) { initialize_buckets }
99
101
 
100
102
  while !buckets.empty?
101
103
  # keeping leader state as long as buckets are available by renominating before
102
104
  # nomination times out
103
- as_dictator { update_buckets } unless restart_wanted?
105
+ as_dictator(memcache_client) { update_buckets } unless restart_wanted?(memcache_client)
104
106
  end
105
107
  end
106
108
 
107
109
  with_errors_logged('termination handling') do
108
- if restart_wanted?
110
+ if restart_wanted?(memcache_client)
109
111
  log.info "restart triggered"
110
- as_dictator { populate_followers_to_stop }
112
+ as_dictator(memcache_client) { populate_followers_to_stop }
111
113
  # keeping leader state as long as there are followers to stop
112
114
  while !followers_to_stop.empty?
113
115
  log.info "waiting fo workers to stop: #{followers_to_stop}"
114
116
  relax(until_next_iteration / 2)
115
- seize_leadership
117
+ seize_leadership(memcache_client)
116
118
  end
117
119
  log.info "leader exiting due to trigger"
118
120
  exit 0
@@ -129,7 +131,8 @@ module Politics
129
131
  end
130
132
 
131
133
  def bucket_request(requestor_uri, context)
132
- if leader?
134
+ memcache_client = client_for(memcache_config)
135
+ if leader?(memcache_client)
133
136
  log.debug "delivering bucket request"
134
137
  bucket_spec = next_bucket(requestor_uri, context)
135
138
  if !bucket_spec[0] && @followers_to_stop.include?(requestor_uri)
@@ -162,27 +165,27 @@ module Politics
162
165
  true
163
166
  end
164
167
 
165
- def leader
168
+ def leader(memcache_client)
166
169
  2.times do
167
- break if leader_uri
170
+ break if leader_uri(memcache_client)
168
171
  log.debug "could not determine leader - relaxing until next iteration"
169
172
  relax until_next_iteration
170
173
  end
171
- raise "cannot determine leader" unless leader_uri
172
- DRbObject.new(nil, leader_uri)
174
+ raise "cannot determine leader" unless leader_uri(memcache_client)
175
+ DRbObject.new(nil, leader_uri(memcache_client))
173
176
  end
174
177
 
175
178
  def find_workers
176
179
  raise "Please provide a method ”find_workers” returning a list of all other worker URIs"
177
180
  end
178
181
 
179
- def restart_wanted?
182
+ def restart_wanted?(memcache_client)
180
183
  memcache_client.get(restart_flag)
181
184
  end
182
185
 
183
186
  private
184
187
 
185
- attr_reader :iteration_end, :memcache_client
188
+ attr_reader :iteration_end, :memcache_config
186
189
 
187
190
  def with_errors_logged(task)
188
191
  yield
@@ -243,9 +246,9 @@ module Politics
243
246
  "#{group_name}_restart"
244
247
  end
245
248
 
246
- def internal_cleanup
247
- log.debug("uri: #{uri}, leader_uri: #{leader_uri}, until_next_iteration: #{until_next_iteration}")
248
- if leader?
249
+ def internal_cleanup(memcache_client)
250
+ log.debug("uri: #{uri}, leader_uri: #{leader_uri(memcache_client)}, until_next_iteration: #{until_next_iteration}")
251
+ if leader?(memcache_client)
249
252
  memcache_client.delete(token)
250
253
  memcache_client.delete(restart_flag)
251
254
  end
@@ -261,7 +264,7 @@ module Politics
261
264
 
262
265
  # Nominate ourself as leader by contacting the memcached server
263
266
  # and attempting to add the token with our name attached.
264
- def nominate
267
+ def nominate(memcache_client)
265
268
  log.debug("try to nominate")
266
269
  start_iteration {|duration| memcache_client.add(token, uri, duration) }
267
270
  end
@@ -272,14 +275,14 @@ module Politics
272
275
  @leader_uri = nil
273
276
  end
274
277
 
275
- def leader_uri
278
+ def leader_uri(memcache_client)
276
279
  @leader_uri ||= memcache_client.get(token)
277
280
  end
278
281
 
279
282
  # Check to see if we are leader by looking at the process name
280
283
  # associated with the token.
281
- def leader?
282
- until_next_iteration > 0 && uri == leader_uri
284
+ def leader?(memcache_client)
285
+ until_next_iteration > 0 && uri == leader_uri(memcache_client)
283
286
  end
284
287
 
285
288
  # Easy to mock or monkey-patch if another MemCache client is preferred.
@@ -268,14 +268,14 @@ describe Worker do
268
268
  describe "when determining if restart is wanted" do
269
269
  it "should return true if the restart flag is set in memcache" do
270
270
  expect(memcache_client).to receive(:get).with('worker_restart').and_return true
271
- expect(worker).to be_restart_wanted
271
+ expect(worker).to be_restart_wanted(memcache_client)
272
272
  end
273
273
 
274
274
  it "should return false if the restart flag is not set in memcache" do
275
275
  expect(memcache_client).to receive(:get).with('worker_restart').and_return false
276
- expect(worker).not_to be_restart_wanted
276
+ expect(worker).not_to be_restart_wanted(memcache_client)
277
277
  expect(memcache_client).to receive(:get).with('worker_restart').and_return nil
278
- expect(worker).not_to be_restart_wanted
278
+ expect(worker).not_to be_restart_wanted(memcache_client)
279
279
  end
280
280
  end
281
281
 
@@ -291,7 +291,7 @@ describe Worker do
291
291
 
292
292
  it "performs before_perform_leader_duties callback" do
293
293
  expect(worker).to receive(:before_perform_leader_duties)
294
- worker.perform_leader_duties
294
+ worker.perform_leader_duties(memcache_client)
295
295
  end
296
296
 
297
297
  it "has a before_perform_leader_duties callback" do
@@ -299,10 +299,10 @@ describe Worker do
299
299
  end
300
300
 
301
301
  it "should initialize buckets as dictator" do
302
- expect(worker).to receive(:seize_leadership).with(666).ordered
302
+ expect(worker).to receive(:seize_leadership).with(memcache_client, 666).ordered
303
303
  expect(worker).to receive(:initialize_buckets).ordered
304
304
  expect(worker).to receive(:seize_leadership).ordered
305
- worker.perform_leader_duties
305
+ worker.perform_leader_duties(memcache_client)
306
306
  end
307
307
 
308
308
  describe "as long as there are buckets" do
@@ -313,32 +313,32 @@ describe Worker do
313
313
 
314
314
  it "should update buckets periodically" do
315
315
  expect(worker).to receive(:update_buckets).exactly(4).times
316
- worker.perform_leader_duties
316
+ worker.perform_leader_duties(memcache_client)
317
317
  end
318
318
 
319
319
  it "should relax half of the time to the next iteration" do
320
320
  allow(worker).to receive(:until_next_iteration).and_return(6)
321
321
  expect(worker).to receive(:relax).with(3).exactly(4).times
322
- worker.perform_leader_duties
322
+ worker.perform_leader_duties(memcache_client)
323
323
  end
324
324
 
325
325
  it "should seize the leadership periodically" do
326
326
  expect(worker).to receive(:seize_leadership).at_least(4).times
327
- worker.perform_leader_duties
327
+ worker.perform_leader_duties(memcache_client)
328
328
  end
329
329
 
330
330
  it "should seize the leadership periodically even if restart is wanted" do
331
331
  allow(worker).to receive(:restart_wanted?).and_return true
332
332
  allow(worker).to receive(:exit)
333
333
  expect(worker).to receive(:seize_leadership).at_least(4).times
334
- worker.perform_leader_duties
334
+ worker.perform_leader_duties(memcache_client)
335
335
  end
336
336
 
337
337
  it "should not update buckets if restart is wanted" do
338
338
  allow(worker).to receive(:restart_wanted?).and_return true
339
339
  allow(worker).to receive(:exit)
340
340
  expect(worker).not_to receive(:update_buckets)
341
- worker.perform_leader_duties
341
+ worker.perform_leader_duties(memcache_client)
342
342
  end
343
343
  end
344
344
 
@@ -356,7 +356,7 @@ describe Worker do
356
356
  it "populates the followers_to_stop list before evaluating it" do
357
357
  expect(worker).to receive(:populate_followers_to_stop).ordered.once
358
358
  expect(worker).to receive(:followers_to_stop).ordered.and_return []
359
- worker.perform_leader_duties
359
+ worker.perform_leader_duties(memcache_client)
360
360
  end
361
361
 
362
362
  context "as long as there are followers to stop" do
@@ -369,12 +369,12 @@ describe Worker do
369
369
  it "relaxes half of the time to the next iteration" do
370
370
  allow(worker).to receive(:until_next_iteration).and_return(6)
371
371
  expect(worker).to receive(:relax).with(3).exactly(2).times
372
- worker.perform_leader_duties
372
+ worker.perform_leader_duties(memcache_client)
373
373
  end
374
374
 
375
375
  it "seizes the leadership periodically" do
376
376
  expect(worker).to receive(:seize_leadership).at_least(2).times
377
- worker.perform_leader_duties
377
+ worker.perform_leader_duties(memcache_client)
378
378
  end
379
379
  end
380
380
 
@@ -385,7 +385,7 @@ describe Worker do
385
385
 
386
386
  it "exits" do
387
387
  expect(worker).to receive(:exit).with(0)
388
- worker.perform_leader_duties
388
+ worker.perform_leader_duties(memcache_client)
389
389
  end
390
390
  end
391
391
  end
@@ -398,7 +398,7 @@ describe Worker do
398
398
  it "does not populate the followers_to_stop list if restart is not wanted" do
399
399
  allow(worker).to receive(:restart_wanted?).and_return false
400
400
  expect(worker).not_to receive(:populate_followers_to_stop)
401
- worker.perform_leader_duties
401
+ worker.perform_leader_duties(memcache_client)
402
402
  end
403
403
  end
404
404
  end
@@ -413,22 +413,22 @@ describe Worker do
413
413
 
414
414
  it "should set itself to leader" do
415
415
  expect(memcache_client).to receive(:set).with(anything(), 'myself', anything())
416
- worker.seize_leadership
416
+ worker.seize_leadership(memcache_client)
417
417
  end
418
418
 
419
419
  it "should seize the leadership for the amount of seconds given" do
420
420
  expect(memcache_client).to receive(:set).with(anything(), anything(), 666)
421
- worker.seize_leadership 666
421
+ worker.seize_leadership memcache_client, 666
422
422
  end
423
423
 
424
424
  it "should seize the leadership for iteration_length if no duration is given" do
425
425
  expect(memcache_client).to receive(:set).with(anything(), anything(), 123)
426
- worker.seize_leadership
426
+ worker.seize_leadership(memcache_client)
427
427
  end
428
428
 
429
429
  it "should seize the leadership for the worker's group" do
430
430
  expect(memcache_client).to receive(:set).with('dcc-group', anything(), anything())
431
- worker.seize_leadership
431
+ worker.seize_leadership(memcache_client)
432
432
  end
433
433
 
434
434
  it "should have the next iteration exactly when the seized leadership ends" do
@@ -436,13 +436,13 @@ describe Worker do
436
436
  allow(Time).to receive(:now).and_return now
437
437
  end_of_leadership = now + 666
438
438
 
439
- worker.seize_leadership 666
439
+ worker.seize_leadership memcache_client, 666
440
440
  expect(worker.until_next_iteration).to eq(666)
441
441
 
442
- worker.seize_leadership
442
+ worker.seize_leadership(memcache_client)
443
443
  expect(worker.until_next_iteration).to eq(123)
444
444
 
445
- worker.seize_leadership 6
445
+ worker.seize_leadership memcache_client, 6
446
446
  expect(worker.until_next_iteration).to eq(6)
447
447
  end
448
448
  end
@@ -483,24 +483,24 @@ describe Worker do
483
483
  it "should return a drb object with the leader uri" do
484
484
  allow(worker).to receive(:leader_uri).and_return("leader's uri")
485
485
  expect(DRbObject).to receive(:new).with(nil, "leader's uri").and_return "leader"
486
- expect(worker.leader).to eq("leader")
486
+ expect(worker.leader(memcache_client)).to eq("leader")
487
487
  end
488
488
 
489
489
  it "should try three times to get the leader on anarchy (no leader)" do
490
490
  expect(worker).to receive(:leader_uri).at_least(3).times.and_return nil
491
- worker.leader rescue nil
491
+ worker.leader(memcache_client) rescue nil
492
492
  end
493
493
 
494
494
  it "should raise an error when leader cannot be determined during anarchy" do
495
495
  allow(worker).to receive(:leader_uri).and_return nil
496
- expect {worker.leader}.to raise_error(/cannot determine leader/)
496
+ expect {worker.leader(memcache_client)}.to raise_error(/cannot determine leader/)
497
497
  end
498
498
 
499
499
  it "should sleep until next iteration before retrying to get leader" do
500
500
  allow(worker).to receive(:leader_uri).and_return nil
501
501
  allow(worker).to receive(:until_next_iteration).and_return 666
502
502
  expect(worker).to receive(:relax).with(666).exactly(2).times
503
- worker.leader rescue nil
503
+ worker.leader(memcache_client) rescue nil
504
504
  end
505
505
  end
506
506
 
@@ -517,12 +517,12 @@ describe Worker do
517
517
 
518
518
  it "should remove the leadership token from memcache" do
519
519
  expect(memcache_client).to receive(:delete).with('the group_token')
520
- worker.send(:internal_cleanup)
520
+ worker.send(:internal_cleanup, memcache_client)
521
521
  end
522
522
 
523
523
  it "should remove the restart wanted flag from memcache" do
524
524
  expect(memcache_client).to receive(:delete).with('the group_restart')
525
- worker.send(:internal_cleanup)
525
+ worker.send(:internal_cleanup, memcache_client)
526
526
  end
527
527
  end
528
528
 
@@ -533,7 +533,7 @@ describe Worker do
533
533
 
534
534
  it "should not remove anything from memcache" do
535
535
  expect(memcache_client).not_to receive(:delete)
536
- worker.send(:internal_cleanup)
536
+ worker.send(:internal_cleanup, memcache_client)
537
537
  end
538
538
  end
539
539
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: infopark-politics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.4
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-04-15 00:00:00.000000000 Z
12
+ date: 2015-04-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec