poseidon 0.0.1

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