poseidon 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 768653a82da925b840342126faf304153c1b1455
4
+ data.tar.gz: 82c3ed1cd5746d582666e7e04aec8cecca986b91
5
+ SHA512:
6
+ metadata.gz: e67ed28694dcb0c8f1596ada7a61b6c53ddaf36c639eaf6cbd69fa95390daefdef901cf587057778aa6776ad769f9046bc66db34e1731ea1efff4f0d6f58a04f
7
+ data.tar.gz: 861af0b1788b241e59de63a87514d3af0a60d04f6d9b14dca22966a4172a5c45c19888bd0ff1da0aa9df575829d1879d9e1e3c3cf3aebff4a7243a02fc65707e
@@ -0,0 +1,8 @@
1
+ # 0.0.2
2
+
3
+ * Added ability to create a partitioner consumer for a topic+partition using topic metadata.
4
+ * Added PartitionConsumer#offset to return offset of the last fetch
5
+
6
+ # 0.0.1
7
+
8
+ * Initial release
data/README.md CHANGED
@@ -4,10 +4,13 @@ Poseidon is a Kafka client. Poseidon only supports the 0.8 API and above.
4
4
 
5
5
  **Until 1.0.0 this should be considered ALPHA software and not neccessarily production ready.**
6
6
 
7
- * [API Documentation](http://rubydoc.info/github/bpot/poseidon)
8
-
9
7
  ## Usage
10
8
 
9
+ ### API Documentation
10
+
11
+ * [Latest release](http://rubydoc.info/gems/poseidon)
12
+ * [Github master](http://rubydoc.info/github/bpot/poseidon)
13
+
11
14
  ### Installing a Kafka broker locally
12
15
 
13
16
  Follow the [instructions](https://cwiki.apache.org/KAFKA/kafka-08-quick-start.html) on the Kafka wiki to build Kafka 0.8 and get a test broker up and running.
@@ -47,6 +47,16 @@ module Poseidon
47
47
  @brokers[broker_id]
48
48
  end
49
49
 
50
+ # Return lead broker for topic and partition
51
+ def lead_broker_for_partition(topic_name, partition)
52
+ broker_id = @topic_metadata[topic_name].partition_leader(partition)
53
+ if broker_id
54
+ @brokers[broker_id]
55
+ else
56
+ nil
57
+ end
58
+ end
59
+
50
60
  private
51
61
  def update_topics(topics)
52
62
  topics.each do |topic|
@@ -10,6 +10,25 @@ module Poseidon
10
10
  # as recent as the last fetch call.
11
11
  attr_reader :highwater_mark
12
12
 
13
+ attr_reader :host, :port
14
+
15
+ attr_reader :offset
16
+
17
+ # Returns a consumer pointing at the lead broker for the partition.
18
+ #
19
+ # Eventually this will be replaced by higher level consumer functionality,
20
+ # this is a stop-gap.
21
+ #
22
+ def self.consumer_for_partition(client_id, seed_brokers, topic, partition, offset, options = {})
23
+ broker_pool = BrokerPool.new(client_id, seed_brokers)
24
+
25
+ cluster_metadata = ClusterMetadata.new
26
+ cluster_metadata.update(broker_pool.fetch_metadata([topic]))
27
+
28
+ broker = cluster_metadata.lead_broker_for_partition(topic, partition)
29
+ new(client_id, broker.host, broker.port, topic, partition, offset, options)
30
+ end
31
+
13
32
  # Create a new consumer which reads the specified topic and partition from
14
33
  # the host.
15
34
  #
@@ -37,6 +56,9 @@ module Poseidon
37
56
  #
38
57
  # @api public
39
58
  def initialize(client_id, host, port, topic, partition, offset, options = {})
59
+ @host = host
60
+ @port = port
61
+
40
62
  @connection = Connection.new(host, port, client_id)
41
63
  @topic = topic
42
64
  @partition = partition
@@ -61,5 +61,14 @@ module Poseidon
61
61
  def available_partition_count
62
62
  @available_partition_count ||= available_partition_leader_ids.count
63
63
  end
64
+
65
+ def partition_leader(partition_id)
66
+ partition = struct.partitions.find { |p| p.id == partition_id }
67
+ if partition
68
+ partition.leader
69
+ else
70
+ nil
71
+ end
72
+ end
64
73
  end
65
74
  end
@@ -1,4 +1,4 @@
1
1
  module Poseidon
2
2
  # Unstable! API May Change!
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
@@ -11,6 +11,7 @@ Gem::Specification.new do |gem|
11
11
  gem.description = %q{A Kafka (http://kafka.apache.org/) producer and consumer}
12
12
  gem.summary = %q{Poseidon is a producer and consumer implementation for Kafka >= 0.8}
13
13
  gem.homepage = "https://github.com/bpot/poseidon"
14
+ gem.licenses = ["MIT"]
14
15
 
15
16
  gem.files = `git ls-files`.split($/)
16
17
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -0,0 +1,43 @@
1
+ require 'integration/multiple_brokers/spec_helper'
2
+
3
+ describe "consuming with multiple brokers" do
4
+ before(:each) do
5
+ # autocreate the topic by asking for information about it
6
+ c = Connection.new("localhost", 9092, "metadata_fetcher")
7
+ md = c.topic_metadata(["test"])
8
+ sleep 1
9
+ end
10
+
11
+ it "finds the lead broker for each partition" do
12
+ brokers = Set.new
13
+ 0.upto(2) do |partition|
14
+ pc = PartitionConsumer.consumer_for_partition("test_client",
15
+ ["localhost:9092"],
16
+ "test", partition,
17
+ :earliest_offset)
18
+
19
+ brokers.add("#{pc.host}:#{pc.port}")
20
+ end
21
+ expect(brokers.size).to eq(3)
22
+ end
23
+
24
+ it "consumes from all partitions" do
25
+ @p = Producer.new(["localhost:9092","localhost:9093","localhost:9094"], "test",
26
+ :required_acks => 1)
27
+
28
+ msgs = 24.times.map { |n| "hello_#{n}" }
29
+ msgs.each do |msg|
30
+ @p.send_messages([MessageToSend.new("test", msg)])
31
+ end
32
+
33
+ fetched_messages = []
34
+ 0.upto(2) do |partition|
35
+ pc = PartitionConsumer.consumer_for_partition("test_client",
36
+ ["localhost:9092"],
37
+ "test", partition,
38
+ :earliest_offset)
39
+ fetched_messages.push(*pc.fetch)
40
+ end
41
+ expect(fetched_messages.map(&:value).sort).to eq(msgs.sort)
42
+ end
43
+ end
@@ -5,8 +5,8 @@ describe ClusterMetadata do
5
5
  describe "populated" do
6
6
  before(:each) do
7
7
  partitions = [
8
- PartitionMetadata.new(1, 1, [1,2], [1,2], nil),
9
- PartitionMetadata.new(2, 2, [2,1], [2,1], nil)
8
+ PartitionMetadata.new(nil, 1, 1, [1,2], [1,2]),
9
+ PartitionMetadata.new(nil, 2, 2, [2,1], [2,1])
10
10
  ]
11
11
  topics = [TopicMetadata.new(TopicMetadataStruct.new(nil, "test", partitions))]
12
12
 
@@ -37,5 +37,10 @@ describe ClusterMetadata do
37
37
  broker = @cm.broker(1)
38
38
  expect(broker).to eq(@mr.brokers.first)
39
39
  end
40
+
41
+ it "provides the lead broker for a partition" do
42
+ expect(@cm.lead_broker_for_partition("test",1).id).to eq(1)
43
+ expect(@cm.lead_broker_for_partition("test",2).id).to eq(2)
44
+ end
40
45
  end
41
46
  end
@@ -3,15 +3,23 @@ require 'spec_helper'
3
3
  describe TopicMetadata do
4
4
  context "encoding" do
5
5
  it "roundtrips" do
6
- partition_metadata = PartitionMetadata.new(0, 0, 0, [0], [0])
6
+ partition_metadata = Protocol::PartitionMetadata.new(0, 0, 0, [0], [0])
7
7
  partitions = [partition_metadata]
8
- tm = TopicMetadata.new(TopicMetadataStruct.new(0, "topic", partitions))
8
+ tm = TopicMetadata.new(Protocol::TopicMetadataStruct.new(0, "topic", partitions))
9
9
 
10
- request_buffer = RequestBuffer.new
10
+ request_buffer = Protocol::RequestBuffer.new
11
11
  tm.write(request_buffer)
12
12
 
13
- response_buffer = ResponseBuffer.new(request_buffer.to_s)
13
+ response_buffer = Protocol::ResponseBuffer.new(request_buffer.to_s)
14
14
  expect(TopicMetadata.read(response_buffer)).to eq(tm)
15
15
  end
16
16
  end
17
+
18
+ it 'determines leader for a partition' do
19
+ partition_metadata = Protocol::PartitionMetadata.new(0, 0, 0, [0], [0])
20
+ partitions = [partition_metadata]
21
+ tm = TopicMetadata.new(Protocol::TopicMetadataStruct.new(0, "topic", partitions))
22
+
23
+ expect(tm.partition_leader(0)).to eq(0)
24
+ end
17
25
  end
metadata CHANGED
@@ -1,78 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: poseidon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.0.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Bob Potter
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-09-11 00:00:00.000000000 Z
11
+ date: 2013-09-19 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rspec
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: yard
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: simplecov
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: daemon_controller
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - '>='
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - '>='
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  description: A Kafka (http://kafka.apache.org/) producer and consumer
@@ -86,6 +77,7 @@ files:
86
77
  - .rspec
87
78
  - .travis.yml
88
79
  - .yardopts
80
+ - CHANGES.md
89
81
  - Gemfile
90
82
  - LICENSE.txt
91
83
  - README.md
@@ -121,6 +113,7 @@ files:
121
113
  - lib/poseidon/version.rb
122
114
  - poseidon.gemspec
123
115
  - spec/bin/kafka-run-class.sh
116
+ - spec/integration/multiple_brokers/consumer_spec.rb
124
117
  - spec/integration/multiple_brokers/round_robin_spec.rb
125
118
  - spec/integration/multiple_brokers/spec_helper.rb
126
119
  - spec/integration/simple/compression_spec.rb
@@ -150,31 +143,32 @@ files:
150
143
  - spec/unit/sync_producer_spec.rb
151
144
  - spec/unit/topic_metadata_spec.rb
152
145
  homepage: https://github.com/bpot/poseidon
153
- licenses: []
146
+ licenses:
147
+ - MIT
148
+ metadata: {}
154
149
  post_install_message:
155
150
  rdoc_options: []
156
151
  require_paths:
157
152
  - lib
158
153
  required_ruby_version: !ruby/object:Gem::Requirement
159
- none: false
160
154
  requirements:
161
- - - ! '>='
155
+ - - '>='
162
156
  - !ruby/object:Gem::Version
163
157
  version: '0'
164
158
  required_rubygems_version: !ruby/object:Gem::Requirement
165
- none: false
166
159
  requirements:
167
- - - ! '>='
160
+ - - '>='
168
161
  - !ruby/object:Gem::Version
169
162
  version: '0'
170
163
  requirements: []
171
164
  rubyforge_project:
172
- rubygems_version: 1.8.23
165
+ rubygems_version: 2.0.2
173
166
  signing_key:
174
- specification_version: 3
167
+ specification_version: 4
175
168
  summary: Poseidon is a producer and consumer implementation for Kafka >= 0.8
176
169
  test_files:
177
170
  - spec/bin/kafka-run-class.sh
171
+ - spec/integration/multiple_brokers/consumer_spec.rb
178
172
  - spec/integration/multiple_brokers/round_robin_spec.rb
179
173
  - spec/integration/multiple_brokers/spec_helper.rb
180
174
  - spec/integration/simple/compression_spec.rb