promiscuous-poseidon_cluster 0.3.0 → 0.4.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: f7653a5f9ee3e08c3ccda22787d2a9da5b752b86
4
- data.tar.gz: 6447aadb67ad485dc77e79ea91af4d3b99bd49e1
3
+ metadata.gz: b88185138e6a8e8de7ce363a550b4630f6e95c8f
4
+ data.tar.gz: b234eaee3e59a7441458f4506a09fd5c5e929e2e
5
5
  SHA512:
6
- metadata.gz: 203099eb7d08fa1f80dd197c5e4094352291dc197a4e8137efde19450a4c4224e2cdc23bfdc9dd6789607c0544c326ce329c3c81bbd1d7a30f557f30ae0deddb
7
- data.tar.gz: d78680cc99b1dd11fb11183f00fc4186835e8515ade5ae933b10d0a39a55f7bb0f5a99afb2d68e371198659402a20b421b6e9b80f3700006b941e7462a094889
6
+ metadata.gz: 167be7e9484234a3fd4d282567c1230d1d231463be6ed38bb0adfbddfcc91d198de5af2d636caa0a2b588044afbd9e0c43948a6b10d4ffdd0f581104ac334318
7
+ data.tar.gz: 3952e0a94d4efe8ef020812ba0dd6b9379b4bdbe530cfbcb61da532a2286eaff5a79c6574fe772e5168cd11605bdc80b9b77a2313a83f49cc263e7bf365d445a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- poseidon_cluster (0.3.0)
4
+ poseidon_cluster (0.4.0)
5
5
  poseidon (>= 0.0.5.pre1)
6
6
  zk
7
7
 
@@ -22,7 +22,7 @@ GEM
22
22
  multi_json (>= 1.8.4)
23
23
  mime-types (2.3)
24
24
  multi_json (1.10.1)
25
- poseidon (0.0.5.pre1)
25
+ poseidon (0.0.5)
26
26
  rake (10.3.2)
27
27
  rest-client (1.6.7)
28
28
  mime-types (>= 1.16)
@@ -53,13 +53,10 @@ GEM
53
53
  thor (0.19.1)
54
54
  tins (1.3.0)
55
55
  yard (0.8.7.4)
56
- zk (1.9.4)
56
+ zk (1.9.5)
57
57
  logging (~> 1.8.2)
58
58
  zookeeper (~> 1.4.0)
59
- zookeeper (1.4.9)
60
- zookeeper (1.4.9-java)
61
- slyphon-log4j (= 1.2.15)
62
- slyphon-zookeeper_jar (= 3.3.5)
59
+ zookeeper (1.4.10)
63
60
 
64
61
  PLATFORMS
65
62
  java
@@ -1,9 +1,9 @@
1
1
  require 'socket'
2
- require 'timeout'
3
- require 'zk'
4
- require 'poseidon'
5
2
  require 'thread'
6
3
 
4
+ require 'poseidon'
5
+ require 'zk'
6
+
7
7
  module Poseidon::Cluster
8
8
  MAX_INT32 = 0x7fffffff
9
9
  @@sem = Mutex.new
@@ -12,17 +12,22 @@ module Poseidon::Cluster
12
12
  # @return [Integer] an incremented number
13
13
  # @api private
14
14
  def self.inc!
15
- @@sem.synchronize { @@inc += 1; @@inc = 1 if @@inc > MAX_INT32; @@inc }
15
+ @@sem.synchronize do
16
+ @@inc += 1;
17
+
18
+ if @@inc > MAX_INT32
19
+ @@inc = 1
20
+ end
21
+
22
+ @@inc
23
+ end
16
24
  end
17
25
 
18
26
  # @return [String] an globally unique identifier
19
27
  # @api private
20
28
  def self.guid
21
- [::Socket.gethostname, ::Process.pid, ::Time.now.to_i, inc!].join("-")
29
+ [::Socket.gethostname, ::Process.pid, ::Time.now.nsec, inc!].join('-')
22
30
  end
23
-
24
31
  end
25
32
 
26
- %w|consumer_group|.each do |name|
27
- require "poseidon/#{name}"
28
- end
33
+ require 'poseidon/consumer_group'
@@ -21,7 +21,7 @@
21
21
  #
22
22
  # @api public
23
23
  class Poseidon::ConsumerGroup
24
- DEFAULT_CLAIM_TIMEOUT = 30
24
+ DEFAULT_CLAIM_TIMEOUT = 5
25
25
  DEFAULT_LOOP_DELAY = 1
26
26
 
27
27
  # Poseidon::ConsumerGroup::Consumer is internally used by Poseidon::ConsumerGroup.
@@ -41,7 +41,6 @@ class Poseidon::ConsumerGroup
41
41
  options.delete(:trail)
42
42
  super group.id, broker.host, broker.port, group.topic, partition, offset, options
43
43
  end
44
-
45
44
  end
46
45
 
47
46
  # @param [Integer] pnum number of partitions size
@@ -97,7 +96,7 @@ class Poseidon::ConsumerGroup
97
96
  def initialize(name, brokers, zookeepers, topic, options = {})
98
97
  @name = name
99
98
  @topic = topic
100
- @zk = ::ZK.new(zookeepers.join(","))
99
+ @zk = ::ZK.new(zookeepers.join(','), {:thread => :per_callback})
101
100
  # Poseidon::BrokerPool doesn't provide default value for this option
102
101
  # Configuring default value like this isn't beautiful, though.. by kssminus
103
102
  options[:socket_timeout_ms] ||= 10000
@@ -147,8 +146,8 @@ class Poseidon::ConsumerGroup
147
146
  registries.each do |_, path|
148
147
  zk.mkdir_p(path)
149
148
  end
150
- zk.create(consumer_path, "{}", ephemeral: true)
151
- zk.register(registries[:consumer]) {|_| rebalance! }
149
+ zk.create(consumer_path, "{}", {:ephemeral => true})
150
+ zk.register(registries[:consumer]) { rebalance! }
152
151
 
153
152
  # Rebalance
154
153
  rebalance!
@@ -156,10 +155,12 @@ class Poseidon::ConsumerGroup
156
155
  end
157
156
 
158
157
  # Reloads metadata/broker/partition information
159
- def reload
160
- @metadata = @topic_metadata = nil
158
+ def reload_metadata
159
+ @metadata = nil; @topic_metadata = nil
161
160
  metadata
162
- self
161
+ topic_metadata
162
+
163
+ true
163
164
  end
164
165
 
165
166
  # Closes the consumer group gracefully, only really useful in tests
@@ -178,7 +179,7 @@ class Poseidon::ConsumerGroup
178
179
  # @param [Integer] partition
179
180
  # @return [Integer] the latest stored offset for the given partition
180
181
  def offset(partition)
181
- data, _ = zk.get offset_path(partition), ignore: :no_node
182
+ data, _ = zk.get(offset_path(partition), {:ignore => :no_node})
182
183
  data.to_i
183
184
  end
184
185
 
@@ -186,9 +187,9 @@ class Poseidon::ConsumerGroup
186
187
  # @param [Integer] partition
187
188
  # @param [Integer] offset
188
189
  def commit(partition, offset)
189
- zk.set offset_path(partition), offset.to_s
190
+ zk.set(offset_path(partition), offset.to_s)
190
191
  rescue ZK::Exceptions::NoNode
191
- zk.create offset_path(partition), offset.to_s, ignore: :node_exists
192
+ zk.create(offset_path(partition), offset.to_s, {:ignore => :node_exists})
192
193
  end
193
194
 
194
195
  # Sorted partitions by broker address (so partitions on the same broker are clustered together)
@@ -198,7 +199,7 @@ class Poseidon::ConsumerGroup
198
199
 
199
200
  topic_metadata.available_partitions.sort_by do |part|
200
201
  broker = metadata.brokers[part.leader]
201
- [broker.host, broker.port].join(":")
202
+ [broker.host, broker.port].join(':')
202
203
  end
203
204
  end
204
205
 
@@ -239,6 +240,7 @@ class Poseidon::ConsumerGroup
239
240
  unless opts[:commit] == false || commit == false
240
241
  commit consumer.partition, consumer.offset
241
242
  end
243
+
242
244
  true
243
245
  end
244
246
 
@@ -345,7 +347,7 @@ class Poseidon::ConsumerGroup
345
347
  # Yield over an empty array if nothing claimed,
346
348
  # to allow user to e.g. break out of the loop
347
349
  unless ok
348
- yield -1, []
350
+ yield(-1, [])
349
351
  end
350
352
 
351
353
  # Sleep if either not claimes or nothing returned
@@ -366,28 +368,21 @@ class Poseidon::ConsumerGroup
366
368
  # * let POS be our index position in CG and let N = size(PT)/size(CG)
367
369
  # * assign partitions from POS*N to (POS+1)*N-1
368
370
  def rebalance!
369
- return if @pending
370
-
371
- @pending = true
372
371
  @mutex.synchronize do
373
- @pending = nil
374
-
375
372
  release_all!
376
- reload
373
+ reload_metadata
377
374
 
378
- ids = zk.children(registries[:consumer], watch: true)
379
- pms = partitions
380
- rng = self.class.pick(pms.size, ids, id)
375
+ consumer_ids = zk.children(registries[:consumer], {:watch => true}).sort
376
+ partition_list = partitions
377
+ responsible_for = self.class.pick(partition_list.size, consumer_ids, id)
381
378
 
382
- pms[rng].each do |pm|
383
- if @pending
384
- release_all!
385
- break
386
- end
379
+ return if responsible_for.nil?
387
380
 
388
- consumer = claim!(pm.id)
389
- @consumers.push(consumer) if consumer
390
- end if rng
381
+ partition_list[responsible_for].each do |partition|
382
+ if consumer = claim!(partition.id)
383
+ @consumers.push(consumer)
384
+ end
385
+ end
391
386
  end
392
387
  end
393
388
 
@@ -395,26 +390,33 @@ class Poseidon::ConsumerGroup
395
390
  def release_all!
396
391
  @consumers.each {|c| release!(c.partition) }
397
392
  @consumers.clear
393
+
394
+ true
398
395
  end
399
396
 
400
397
  private
401
398
 
402
399
  # Claim the ownership of the partition for this consumer
403
- # @raise [Timeout::Error]
404
400
  def claim!(partition)
405
- path = claim_path(partition)
406
- Timeout.timeout options[:claim_timout] || DEFAULT_CLAIM_TIMEOUT do
407
- while zk.create(path, id, ephemeral: true, ignore: :node_exists).nil?
408
- return if @pending
409
- sleep(0.1)
410
- end
401
+ sleep_duration = 0.1
402
+ num_tries = ((options[:claim_timout] || DEFAULT_CLAIM_TIMEOUT)/sleep_duration).floor.to_i
403
+ created = nil
404
+
405
+ num_tries.times do
406
+ created = zk.create(claim_path(partition), id, {:ephemeral => true, :ignore => :node_exists})
407
+ break if created
408
+
409
+ sleep(sleep_duration)
411
410
  end
412
- Consumer.new self, partition, options.dup
411
+
412
+ return nil unless created
413
+
414
+ Consumer.new(self, partition, options.dup)
413
415
  end
414
416
 
415
417
  # Release ownership of the partition
416
418
  def release!(partition)
417
- zk.delete claim_path(partition), ignore: :no_node
419
+ zk.delete(claim_path(partition), {:ignore => :no_node})
418
420
  end
419
421
 
420
422
  # @return [String] zookeeper ownership claim path
@@ -431,5 +433,4 @@ class Poseidon::ConsumerGroup
431
433
  def consumer_path
432
434
  "#{registries[:consumer]}/#{id}"
433
435
  end
434
-
435
436
  end
@@ -5,10 +5,10 @@ Gem::Specification.new do |s|
5
5
  s.name = File.basename(__FILE__, '.gemspec')
6
6
  s.summary = "Poseidon cluster extensions"
7
7
  s.description = "Cluster extensions for Poseidon, a producer and consumer implementation for Kafka >= 0.8"
8
- s.version = "0.3.0"
8
+ s.version = "0.4.0"
9
9
 
10
- s.authors = ["Black Square Media"]
11
- s.email = "info@blacksquaremedia.com"
10
+ s.authors = ["Black Square Media", "Crowdtap Inc."]
11
+ s.email = "ops@crowdtap.com"
12
12
  s.homepage = "https://github.com/promiscuous-io/poseidon_cluster"
13
13
 
14
14
  s.require_path = 'lib'
@@ -24,5 +24,4 @@ Gem::Specification.new do |s|
24
24
  s.add_development_dependency "rspec-its"
25
25
  s.add_development_dependency "yard"
26
26
  s.add_development_dependency "coveralls"
27
-
28
27
  end
@@ -8,12 +8,12 @@ describe Poseidon::Cluster do
8
8
 
9
9
  (0...5).map do
10
10
  Thread.new { 100.times { described_class.inc! }}
11
- end.each &:join
11
+ end.each(&:join)
12
12
  (described_class.inc! - num).should == 502
13
13
  end
14
14
 
15
15
  it 'should generate GUIDs' do
16
- described_class.guid.should match(/\A[\w\-\.]+?\-\d{1,5}\-\d{10}\-\d{1,3}\z/)
16
+ described_class.guid.should match(/\A[\w\-\.]+?\-\d{1,5}\-\d{9}\-\d{1,3}\z/)
17
17
  end
18
18
 
19
19
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: promiscuous-poseidon_cluster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Black Square Media
8
+ - Crowdtap Inc.
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-01-16 00:00:00.000000000 Z
12
+ date: 2015-04-09 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: poseidon
@@ -124,7 +125,7 @@ dependencies:
124
125
  version: '0'
125
126
  description: Cluster extensions for Poseidon, a producer and consumer implementation
126
127
  for Kafka >= 0.8
127
- email: info@blacksquaremedia.com
128
+ email: ops@crowdtap.com
128
129
  executables: []
129
130
  extensions: []
130
131
  extra_rdoc_files: []