promiscuous-poseidon_cluster 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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: []