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.
- checksums.yaml +7 -0
- data/CHANGES.md +8 -0
- data/README.md +5 -2
- data/lib/poseidon/cluster_metadata.rb +10 -0
- data/lib/poseidon/partition_consumer.rb +22 -0
- data/lib/poseidon/topic_metadata.rb +9 -0
- data/lib/poseidon/version.rb +1 -1
- data/poseidon.gemspec +1 -0
- data/spec/integration/multiple_brokers/consumer_spec.rb +43 -0
- data/spec/unit/cluster_metadata_spec.rb +7 -2
- data/spec/unit/topic_metadata_spec.rb +12 -4
- metadata +20 -26
checksums.yaml
ADDED
@@ -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
|
data/CHANGES.md
ADDED
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
|
data/lib/poseidon/version.rb
CHANGED
data/poseidon.gemspec
CHANGED
@@ -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]
|
9
|
-
PartitionMetadata.new(2, 2, [2,1], [2,1]
|
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.
|
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
|
+
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:
|
165
|
+
rubygems_version: 2.0.2
|
173
166
|
signing_key:
|
174
|
-
specification_version:
|
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
|