poseidon 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/.gitignore +19 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +12 -0
  4. data/.yardopts +8 -0
  5. data/Gemfile +13 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +71 -0
  8. data/Rakefile +17 -0
  9. data/TODO.md +27 -0
  10. data/examples/consumer.rb +18 -0
  11. data/examples/producer.rb +9 -0
  12. data/lib/poseidon/broker_pool.rb +72 -0
  13. data/lib/poseidon/cluster_metadata.rb +63 -0
  14. data/lib/poseidon/compressed_value.rb +23 -0
  15. data/lib/poseidon/compression/gzip_codec.rb +23 -0
  16. data/lib/poseidon/compression/snappy_codec.rb +17 -0
  17. data/lib/poseidon/compression.rb +30 -0
  18. data/lib/poseidon/connection.rb +138 -0
  19. data/lib/poseidon/fetched_message.rb +37 -0
  20. data/lib/poseidon/message.rb +151 -0
  21. data/lib/poseidon/message_conductor.rb +84 -0
  22. data/lib/poseidon/message_set.rb +80 -0
  23. data/lib/poseidon/message_to_send.rb +33 -0
  24. data/lib/poseidon/messages_for_broker.rb +39 -0
  25. data/lib/poseidon/messages_to_send.rb +47 -0
  26. data/lib/poseidon/messages_to_send_batch.rb +27 -0
  27. data/lib/poseidon/partition_consumer.rb +154 -0
  28. data/lib/poseidon/producer.rb +193 -0
  29. data/lib/poseidon/producer_compression_config.rb +36 -0
  30. data/lib/poseidon/protocol/protocol_struct.rb +238 -0
  31. data/lib/poseidon/protocol/request_buffer.rb +78 -0
  32. data/lib/poseidon/protocol/response_buffer.rb +72 -0
  33. data/lib/poseidon/protocol.rb +122 -0
  34. data/lib/poseidon/sync_producer.rb +117 -0
  35. data/lib/poseidon/topic_metadata.rb +65 -0
  36. data/lib/poseidon/version.rb +4 -0
  37. data/lib/poseidon.rb +102 -0
  38. data/poseidon.gemspec +24 -0
  39. data/spec/bin/kafka-run-class.sh +65 -0
  40. data/spec/integration/multiple_brokers/round_robin_spec.rb +39 -0
  41. data/spec/integration/multiple_brokers/spec_helper.rb +34 -0
  42. data/spec/integration/simple/compression_spec.rb +20 -0
  43. data/spec/integration/simple/connection_spec.rb +33 -0
  44. data/spec/integration/simple/multiple_brokers_spec.rb +8 -0
  45. data/spec/integration/simple/simple_producer_and_consumer_spec.rb +97 -0
  46. data/spec/integration/simple/spec_helper.rb +17 -0
  47. data/spec/integration/simple/unavailable_broker_spec.rb +77 -0
  48. data/spec/spec_helper.rb +32 -0
  49. data/spec/test_cluster.rb +205 -0
  50. data/spec/unit/broker_pool_spec.rb +77 -0
  51. data/spec/unit/cluster_metadata_spec.rb +41 -0
  52. data/spec/unit/compression_spec.rb +17 -0
  53. data/spec/unit/connection_spec.rb +4 -0
  54. data/spec/unit/fetched_message_spec.rb +11 -0
  55. data/spec/unit/message_conductor_spec.rb +147 -0
  56. data/spec/unit/message_set_spec.rb +42 -0
  57. data/spec/unit/message_spec.rb +112 -0
  58. data/spec/unit/message_to_send_spec.rb +10 -0
  59. data/spec/unit/messages_for_broker_spec.rb +54 -0
  60. data/spec/unit/messages_to_send_batch_spec.rb +25 -0
  61. data/spec/unit/messages_to_send_spec.rb +63 -0
  62. data/spec/unit/partition_consumer_spec.rb +124 -0
  63. data/spec/unit/producer_compression_config_spec.rb +35 -0
  64. data/spec/unit/producer_spec.rb +45 -0
  65. data/spec/unit/protocol_spec.rb +54 -0
  66. data/spec/unit/sync_producer_spec.rb +141 -0
  67. data/spec/unit/topic_metadata_spec.rb +17 -0
  68. metadata +206 -0
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ include Protocol
3
+ describe RequestCommon do
4
+ it "roundtrips" do
5
+ rc = RequestCommon.new(0,1,2,"client_id")
6
+
7
+ req_buffer = RequestBuffer.new
8
+ rc.write(req_buffer)
9
+
10
+ resp_buffer = ResponseBuffer.new(req_buffer.to_s)
11
+ rc_roundtrip = RequestCommon.read(resp_buffer)
12
+
13
+ expect(rc).to eq(rc_roundtrip)
14
+ end
15
+ end
16
+
17
+ describe MetadataRequest do
18
+ it "roundtrips" do
19
+ rc = RequestCommon.new(0,1,2,"client_id")
20
+ mr = MetadataRequest.new(rc, ["topic1","topic2"])
21
+
22
+ req_buffer = RequestBuffer.new
23
+ mr.write(req_buffer)
24
+
25
+ resp_buffer = ResponseBuffer.new(req_buffer.to_s)
26
+ mr_roundtrip = MetadataRequest.read(resp_buffer)
27
+
28
+ expect(mr).to eq(mr_roundtrip)
29
+ end
30
+ end
31
+
32
+ describe "objects with errors" do
33
+ it "returns objects that have errors" do
34
+ message_set = MessageSet.new
35
+ message_set << Message.new(:value => "value", :key => "key")
36
+ partition_fetch_response = PartitionFetchResponse.new(0, 5, 100, message_set)
37
+ topic_fetch_response = TopicFetchResponse.new('test_topic',
38
+ [partition_fetch_response])
39
+ response = FetchResponse.new(stub('common'), [topic_fetch_response])
40
+
41
+ expect(response.objects_with_errors).to eq([partition_fetch_response])
42
+ end
43
+
44
+ it "raises error when asked" do
45
+ message_set = MessageSet.new
46
+ message_set << Message.new(:value => "value", :key => "key")
47
+ partition_fetch_response = PartitionFetchResponse.new(0, 5, 100, message_set)
48
+ topic_fetch_response = TopicFetchResponse.new('test_topic',
49
+ [partition_fetch_response])
50
+ response = FetchResponse.new(stub('common'), [topic_fetch_response])
51
+
52
+ expect { response.raise_error_if_one_exists }.to raise_error
53
+ end
54
+ end
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+
3
+ describe SyncProducer do
4
+ describe "creation" do
5
+
6
+ it "sets correct defaults" do
7
+ sp = SyncProducer.new(nil,nil)
8
+ expect(sp.ack_timeout_ms).to eq(1500)
9
+ expect(sp.retry_backoff_ms).to eq(100)
10
+ expect(sp.metadata_refresh_interval_ms).to eq(600_000)
11
+ expect(sp.required_acks).to eq(0)
12
+ expect(sp.max_send_retries).to eq(3)
13
+ end
14
+
15
+ it "raises ArgumentError on unknown options" do
16
+ expect { SyncProducer.new(nil,nil,:unknown => true) }.to raise_error(ArgumentError)
17
+ end
18
+ end
19
+
20
+ # Fetches metadata
21
+
22
+ describe "sending" do
23
+ before(:each) do
24
+ Kernel.stub!(:sleep)
25
+
26
+ @broker_pool = stub('broker_pool').as_null_object
27
+ BrokerPool.stub!(:new).and_return(@broker_pool)
28
+
29
+ @cluster_metadata = stub('cluster_metadata', :last_refreshed_at => Time.now).as_null_object
30
+ ClusterMetadata.stub!(:new).and_return(@cluster_metadata)
31
+
32
+ @mbts = stub('messages_to_send', :needs_metadata? => false).as_null_object
33
+ MessagesToSend.stub!(:new).and_return(@mbts)
34
+ end
35
+
36
+ context "needs metadata" do
37
+ before(:each) do
38
+ @mbts.stub!(:needs_metadata?).and_return(true)
39
+ end
40
+
41
+ it "fetches metadata" do
42
+ @broker_pool.should_recieve(:fetch_metadata)
43
+ @sp = SyncProducer.new("test_client", [])
44
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
45
+ end
46
+ end
47
+
48
+ context "there are messages to send" do
49
+ before(:each) do
50
+ @mbts.stub!(:messages_for_brokers).and_return([double('mfb').as_null_object])
51
+ end
52
+
53
+ it "sends messages" do
54
+ @broker_pool.should_recieve(:execute_api_call, :producer, anything, anything, anything)
55
+
56
+ @sp = SyncProducer.new("test_client", [])
57
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
58
+ end
59
+ end
60
+
61
+ context "always fails" do
62
+ before(:each) do
63
+ @mbts.stub!(:all_sent?).and_return(false)
64
+ @sp = SyncProducer.new("test_client", [])
65
+ end
66
+
67
+ it "retries the correct number of times" do
68
+ @mbts.should_receive(:messages_for_brokers).exactly(4).times
69
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
70
+ end
71
+
72
+ it "sleeps the correct amount between retries" do
73
+ Kernel.should_receive(:sleep).with(0.1).exactly(4).times
74
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
75
+ end
76
+
77
+ it "refreshes metadata between retries" do
78
+ @cluster_metadata.should_receive(:update).exactly(4).times
79
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
80
+ end
81
+
82
+ it "returns false" do
83
+ expect(@sp.send_messages([Message.new(:topic => "topic", :value => "value")])).to eq(false)
84
+ end
85
+ end
86
+
87
+ context "no retries" do
88
+ before(:each) do
89
+ @mbts.stub!(:all_sent?).and_return(false)
90
+ @sp = SyncProducer.new("test_client", [], max_send_retries: 0)
91
+ end
92
+
93
+ it "does not call sleep" do
94
+ Kernel.should_receive(:sleep).exactly(0).times
95
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
96
+ end
97
+ end
98
+
99
+ context "succeeds on first attempt" do
100
+ before(:each) do
101
+ @mbts.stub!(:all_sent?).and_return(true)
102
+ @sp = SyncProducer.new("test_client", [])
103
+ end
104
+
105
+ it "returns true" do
106
+ expect(@sp.send_messages([Message.new(:topic => "topic", :value => "value")])).to eq(true)
107
+ end
108
+
109
+ it "does not sleep" do
110
+ Kernel.should_not_receive(:sleep)
111
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
112
+ end
113
+
114
+ it "only attempts to send once" do
115
+ @mbts.should_receive(:messages_for_brokers).once
116
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
117
+ end
118
+ end
119
+
120
+ context "succeeds on second attempt" do
121
+ before(:each) do
122
+ @mbts.stub!(:all_sent?).and_return(false, true)
123
+ @sp = SyncProducer.new("test_client", [])
124
+ end
125
+
126
+ it "returns true" do
127
+ expect(@sp.send_messages([Message.new(:topic => "topic", :value => "value")])).to eq(true)
128
+ end
129
+
130
+ it "sleeps once" do
131
+ Kernel.should_receive(:sleep).once
132
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
133
+ end
134
+
135
+ it "attempts to send twice" do
136
+ @mbts.should_receive(:messages_for_brokers).twice
137
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe TopicMetadata do
4
+ context "encoding" do
5
+ it "roundtrips" do
6
+ partition_metadata = PartitionMetadata.new(0, 0, 0, [0], [0])
7
+ partitions = [partition_metadata]
8
+ tm = TopicMetadata.new(TopicMetadataStruct.new(0, "topic", partitions))
9
+
10
+ request_buffer = RequestBuffer.new
11
+ tm.write(request_buffer)
12
+
13
+ response_buffer = ResponseBuffer.new(request_buffer.to_s)
14
+ expect(TopicMetadata.read(response_buffer)).to eq(tm)
15
+ end
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,206 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: poseidon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Bob Potter
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: yard
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: simplecov
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: daemon_controller
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: A Kafka (http://kafka.apache.org/) producer and consumer
79
+ email:
80
+ - bobby.potter@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - .rspec
87
+ - .travis.yml
88
+ - .yardopts
89
+ - Gemfile
90
+ - LICENSE.txt
91
+ - README.md
92
+ - Rakefile
93
+ - TODO.md
94
+ - examples/consumer.rb
95
+ - examples/producer.rb
96
+ - lib/poseidon.rb
97
+ - lib/poseidon/broker_pool.rb
98
+ - lib/poseidon/cluster_metadata.rb
99
+ - lib/poseidon/compressed_value.rb
100
+ - lib/poseidon/compression.rb
101
+ - lib/poseidon/compression/gzip_codec.rb
102
+ - lib/poseidon/compression/snappy_codec.rb
103
+ - lib/poseidon/connection.rb
104
+ - lib/poseidon/fetched_message.rb
105
+ - lib/poseidon/message.rb
106
+ - lib/poseidon/message_conductor.rb
107
+ - lib/poseidon/message_set.rb
108
+ - lib/poseidon/message_to_send.rb
109
+ - lib/poseidon/messages_for_broker.rb
110
+ - lib/poseidon/messages_to_send.rb
111
+ - lib/poseidon/messages_to_send_batch.rb
112
+ - lib/poseidon/partition_consumer.rb
113
+ - lib/poseidon/producer.rb
114
+ - lib/poseidon/producer_compression_config.rb
115
+ - lib/poseidon/protocol.rb
116
+ - lib/poseidon/protocol/protocol_struct.rb
117
+ - lib/poseidon/protocol/request_buffer.rb
118
+ - lib/poseidon/protocol/response_buffer.rb
119
+ - lib/poseidon/sync_producer.rb
120
+ - lib/poseidon/topic_metadata.rb
121
+ - lib/poseidon/version.rb
122
+ - poseidon.gemspec
123
+ - spec/bin/kafka-run-class.sh
124
+ - spec/integration/multiple_brokers/round_robin_spec.rb
125
+ - spec/integration/multiple_brokers/spec_helper.rb
126
+ - spec/integration/simple/compression_spec.rb
127
+ - spec/integration/simple/connection_spec.rb
128
+ - spec/integration/simple/multiple_brokers_spec.rb
129
+ - spec/integration/simple/simple_producer_and_consumer_spec.rb
130
+ - spec/integration/simple/spec_helper.rb
131
+ - spec/integration/simple/unavailable_broker_spec.rb
132
+ - spec/spec_helper.rb
133
+ - spec/test_cluster.rb
134
+ - spec/unit/broker_pool_spec.rb
135
+ - spec/unit/cluster_metadata_spec.rb
136
+ - spec/unit/compression_spec.rb
137
+ - spec/unit/connection_spec.rb
138
+ - spec/unit/fetched_message_spec.rb
139
+ - spec/unit/message_conductor_spec.rb
140
+ - spec/unit/message_set_spec.rb
141
+ - spec/unit/message_spec.rb
142
+ - spec/unit/message_to_send_spec.rb
143
+ - spec/unit/messages_for_broker_spec.rb
144
+ - spec/unit/messages_to_send_batch_spec.rb
145
+ - spec/unit/messages_to_send_spec.rb
146
+ - spec/unit/partition_consumer_spec.rb
147
+ - spec/unit/producer_compression_config_spec.rb
148
+ - spec/unit/producer_spec.rb
149
+ - spec/unit/protocol_spec.rb
150
+ - spec/unit/sync_producer_spec.rb
151
+ - spec/unit/topic_metadata_spec.rb
152
+ homepage: https://github.com/bpot/poseidon
153
+ licenses: []
154
+ post_install_message:
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ none: false
166
+ requirements:
167
+ - - ! '>='
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubyforge_project:
172
+ rubygems_version: 1.8.23
173
+ signing_key:
174
+ specification_version: 3
175
+ summary: Poseidon is a producer and consumer implementation for Kafka >= 0.8
176
+ test_files:
177
+ - spec/bin/kafka-run-class.sh
178
+ - spec/integration/multiple_brokers/round_robin_spec.rb
179
+ - spec/integration/multiple_brokers/spec_helper.rb
180
+ - spec/integration/simple/compression_spec.rb
181
+ - spec/integration/simple/connection_spec.rb
182
+ - spec/integration/simple/multiple_brokers_spec.rb
183
+ - spec/integration/simple/simple_producer_and_consumer_spec.rb
184
+ - spec/integration/simple/spec_helper.rb
185
+ - spec/integration/simple/unavailable_broker_spec.rb
186
+ - spec/spec_helper.rb
187
+ - spec/test_cluster.rb
188
+ - spec/unit/broker_pool_spec.rb
189
+ - spec/unit/cluster_metadata_spec.rb
190
+ - spec/unit/compression_spec.rb
191
+ - spec/unit/connection_spec.rb
192
+ - spec/unit/fetched_message_spec.rb
193
+ - spec/unit/message_conductor_spec.rb
194
+ - spec/unit/message_set_spec.rb
195
+ - spec/unit/message_spec.rb
196
+ - spec/unit/message_to_send_spec.rb
197
+ - spec/unit/messages_for_broker_spec.rb
198
+ - spec/unit/messages_to_send_batch_spec.rb
199
+ - spec/unit/messages_to_send_spec.rb
200
+ - spec/unit/partition_consumer_spec.rb
201
+ - spec/unit/producer_compression_config_spec.rb
202
+ - spec/unit/producer_spec.rb
203
+ - spec/unit/protocol_spec.rb
204
+ - spec/unit/sync_producer_spec.rb
205
+ - spec/unit/topic_metadata_spec.rb
206
+ has_rdoc: