poseidon 0.0.1 → 0.0.2

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.
@@ -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