codeclimate-poseidon 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +14 -0
  5. data/.yardopts +8 -0
  6. data/CHANGES.md +31 -0
  7. data/Gemfile +13 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +72 -0
  10. data/Rakefile +20 -0
  11. data/TODO.md +27 -0
  12. data/examples/consumer.rb +18 -0
  13. data/examples/producer.rb +9 -0
  14. data/lib/poseidon.rb +120 -0
  15. data/lib/poseidon/broker_pool.rb +86 -0
  16. data/lib/poseidon/cluster_metadata.rb +94 -0
  17. data/lib/poseidon/compressed_value.rb +23 -0
  18. data/lib/poseidon/compression.rb +30 -0
  19. data/lib/poseidon/compression/gzip_codec.rb +23 -0
  20. data/lib/poseidon/compression/snappy_codec.rb +29 -0
  21. data/lib/poseidon/connection.rb +169 -0
  22. data/lib/poseidon/fetched_message.rb +37 -0
  23. data/lib/poseidon/message.rb +151 -0
  24. data/lib/poseidon/message_conductor.rb +86 -0
  25. data/lib/poseidon/message_set.rb +80 -0
  26. data/lib/poseidon/message_to_send.rb +33 -0
  27. data/lib/poseidon/messages_for_broker.rb +56 -0
  28. data/lib/poseidon/messages_to_send.rb +47 -0
  29. data/lib/poseidon/messages_to_send_batch.rb +27 -0
  30. data/lib/poseidon/partition_consumer.rb +225 -0
  31. data/lib/poseidon/producer.rb +199 -0
  32. data/lib/poseidon/producer_compression_config.rb +37 -0
  33. data/lib/poseidon/protocol.rb +122 -0
  34. data/lib/poseidon/protocol/protocol_struct.rb +256 -0
  35. data/lib/poseidon/protocol/request_buffer.rb +77 -0
  36. data/lib/poseidon/protocol/response_buffer.rb +72 -0
  37. data/lib/poseidon/sync_producer.rb +161 -0
  38. data/lib/poseidon/topic_metadata.rb +89 -0
  39. data/lib/poseidon/version.rb +4 -0
  40. data/log/.gitkeep +0 -0
  41. data/poseidon.gemspec +27 -0
  42. data/spec/integration/multiple_brokers/consumer_spec.rb +45 -0
  43. data/spec/integration/multiple_brokers/metadata_failures_spec.rb +144 -0
  44. data/spec/integration/multiple_brokers/rebalance_spec.rb +69 -0
  45. data/spec/integration/multiple_brokers/round_robin_spec.rb +41 -0
  46. data/spec/integration/multiple_brokers/spec_helper.rb +60 -0
  47. data/spec/integration/simple/compression_spec.rb +23 -0
  48. data/spec/integration/simple/connection_spec.rb +35 -0
  49. data/spec/integration/simple/multiple_brokers_spec.rb +10 -0
  50. data/spec/integration/simple/simple_producer_and_consumer_spec.rb +121 -0
  51. data/spec/integration/simple/spec_helper.rb +16 -0
  52. data/spec/integration/simple/truncated_messages_spec.rb +46 -0
  53. data/spec/integration/simple/unavailable_broker_spec.rb +72 -0
  54. data/spec/spec_helper.rb +32 -0
  55. data/spec/test_cluster.rb +211 -0
  56. data/spec/unit/broker_pool_spec.rb +98 -0
  57. data/spec/unit/cluster_metadata_spec.rb +46 -0
  58. data/spec/unit/compression/gzip_codec_spec.rb +34 -0
  59. data/spec/unit/compression/snappy_codec_spec.rb +49 -0
  60. data/spec/unit/compression_spec.rb +17 -0
  61. data/spec/unit/connection_spec.rb +4 -0
  62. data/spec/unit/fetched_message_spec.rb +11 -0
  63. data/spec/unit/message_conductor_spec.rb +164 -0
  64. data/spec/unit/message_set_spec.rb +42 -0
  65. data/spec/unit/message_spec.rb +129 -0
  66. data/spec/unit/message_to_send_spec.rb +10 -0
  67. data/spec/unit/messages_for_broker_spec.rb +54 -0
  68. data/spec/unit/messages_to_send_batch_spec.rb +25 -0
  69. data/spec/unit/messages_to_send_spec.rb +63 -0
  70. data/spec/unit/partition_consumer_spec.rb +142 -0
  71. data/spec/unit/producer_compression_config_spec.rb +42 -0
  72. data/spec/unit/producer_spec.rb +51 -0
  73. data/spec/unit/protocol/request_buffer_spec.rb +16 -0
  74. data/spec/unit/protocol_spec.rb +54 -0
  75. data/spec/unit/sync_producer_spec.rb +156 -0
  76. data/spec/unit/topic_metadata_spec.rb +43 -0
  77. metadata +225 -0
@@ -0,0 +1,156 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.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
+ expect(sp.socket_timeout_ms).to eq(10_000)
14
+ end
15
+
16
+ it "raises ArgumentError on unknown options" do
17
+ expect { SyncProducer.new(nil,nil,:unknown => true) }.to raise_error(ArgumentError)
18
+ end
19
+ end
20
+
21
+ # Fetches metadata
22
+
23
+ describe "sending" do
24
+ before(:each) do
25
+ allow(Kernel).to receive(:sleep)
26
+
27
+ @broker_pool = double('broker_pool').as_null_object
28
+ allow(BrokerPool).to receive(:new).and_return(@broker_pool)
29
+
30
+ @cluster_metadata = double('cluster_metadata', :last_refreshed_at => Time.now).as_null_object
31
+ allow(ClusterMetadata).to receive(:new).and_return(@cluster_metadata)
32
+
33
+ @mbts = double('messages_to_send', :needs_metadata? => false).as_null_object
34
+ allow(MessagesToSend).to receive(:new).and_return(@mbts)
35
+ end
36
+
37
+ context "needs metadata" do
38
+ before(:each) do
39
+ allow(@mbts).to receive(:needs_metadata?).and_return(true)
40
+ end
41
+
42
+ it "fetches metadata" do
43
+ @broker_pool.should_recieve(:fetch_metadata)
44
+
45
+ @sp = SyncProducer.new("test_client", [])
46
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")]) rescue Errors::UnableToFetchMetadata
47
+ end
48
+ end
49
+
50
+ context "there are messages to send" do
51
+ before(:each) do
52
+ allow(@mbts).to receive(:messages_for_brokers).and_return([double('mfb').as_null_object])
53
+ end
54
+
55
+ it "sends messages" do
56
+ @broker_pool.should_recieve(:execute_api_call, :producer, anything, anything, anything)
57
+
58
+ @sp = SyncProducer.new("test_client", [])
59
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")]) rescue StandardError
60
+ end
61
+ end
62
+
63
+ context "always fails" do
64
+ before(:each) do
65
+ allow(@mbts).to receive(:pending_messages?).and_return(true)
66
+ @sp = SyncProducer.new("test_client", [])
67
+ end
68
+
69
+ it "retries the correct number of times" do
70
+ expect(@mbts).to receive(:messages_for_brokers).exactly(4).times
71
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")]) rescue StandardError
72
+ end
73
+
74
+ it "sleeps the correct amount between retries" do
75
+ expect(Kernel).to receive(:sleep).with(0.1).exactly(4).times
76
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")]) rescue StandardError
77
+ end
78
+
79
+ it "resets and refreshes metadata between retries" do
80
+ # First check
81
+ expect(@mbts).to receive(:needs_metadata?).and_return(false).ordered
82
+
83
+ # After first failure
84
+ 3.times do
85
+ expect(@cluster_metadata).to receive(:reset).ordered
86
+ expect(@broker_pool).to receive(:close).ordered
87
+ expect(@mbts).to receive(:needs_metadata?).and_return(true).ordered
88
+ expect(@cluster_metadata).to receive(:update).ordered
89
+ expect(@mbts).to receive(:needs_metadata?).and_return(false).ordered
90
+ end
91
+
92
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")]) rescue StandardError
93
+ end
94
+
95
+ it "raises an exception" do
96
+ expect {
97
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
98
+ }.to raise_error
99
+ end
100
+ end
101
+
102
+ context "no retries" do
103
+ before(:each) do
104
+ allow(@mbts).to receive(:pending_messages?).and_return(true)
105
+ @sp = SyncProducer.new("test_client", [], max_send_retries: 0)
106
+ end
107
+
108
+ it "does not call sleep" do
109
+ expect(Kernel).to receive(:sleep).exactly(0).times
110
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")]) rescue Errors::UnableToFetchMetadata
111
+ end
112
+ end
113
+
114
+ context "succeeds on first attempt" do
115
+ before(:each) do
116
+ allow(@mbts).to receive(:pending_messages?).and_return(false)
117
+ @sp = SyncProducer.new("test_client", [])
118
+ end
119
+
120
+ it "returns true" do
121
+ expect(@sp.send_messages([Message.new(:topic => "topic", :value => "value")])).to eq(true)
122
+ end
123
+
124
+ it "does not sleep" do
125
+ expect(Kernel).not_to receive(:sleep)
126
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
127
+ end
128
+
129
+ it "only attempts to send once" do
130
+ expect(@mbts).to receive(:messages_for_brokers).once
131
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
132
+ end
133
+ end
134
+
135
+ context "succeeds on second attempt" do
136
+ before(:each) do
137
+ allow(@mbts).to receive(:pending_messages?).and_return(true, false)
138
+ @sp = SyncProducer.new("test_client", [])
139
+ end
140
+
141
+ it "returns true" do
142
+ expect(@sp.send_messages([Message.new(:topic => "topic", :value => "value")])).to eq(true)
143
+ end
144
+
145
+ it "sleeps once" do
146
+ expect(Kernel).to receive(:sleep).once
147
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
148
+ end
149
+
150
+ it "attempts to send twice" do
151
+ expect(@mbts).to receive(:messages_for_brokers).twice
152
+ @sp.send_messages([Message.new(:topic => "topic", :value => "value")])
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe TopicMetadata do
4
+ context "encoding" do
5
+ it "roundtrips" do
6
+ partition_metadata = Protocol::PartitionMetadata.new(0, 0, 0, [0], [0])
7
+ partitions = [partition_metadata]
8
+ tm = TopicMetadata.new(Protocol::TopicMetadataStruct.new(0, "topic", partitions))
9
+
10
+ request_buffer = Protocol::RequestBuffer.new
11
+ tm.write(request_buffer)
12
+
13
+ response_buffer = Protocol::ResponseBuffer.new(request_buffer.to_s)
14
+ expect(TopicMetadata.read(response_buffer)).to eq(tm)
15
+ end
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
25
+
26
+ context "#available_partitions" do
27
+ it "includes when missing replicas" do
28
+ partition_metadata = Protocol::PartitionMetadata.new(9, 0, 0, [0], [0])
29
+ partitions = [partition_metadata]
30
+ tm = TopicMetadata.new(Protocol::TopicMetadataStruct.new(0, "topic", partitions))
31
+
32
+ expect(tm.available_partitions.length).to be(1)
33
+ end
34
+
35
+ it "ignores other errors" do
36
+ partition_metadata = Protocol::PartitionMetadata.new(2, 0, 0, [0], [0])
37
+ partitions = [partition_metadata]
38
+ tm = TopicMetadata.new(Protocol::TopicMetadataStruct.new(0, "topic", partitions))
39
+
40
+ expect(tm.available_partitions.length).to be(0)
41
+ end
42
+ end
43
+ end
metadata ADDED
@@ -0,0 +1,225 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: codeclimate-poseidon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8
5
+ platform: ruby
6
+ authors:
7
+ - Bob Potter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: yard
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: simplecov
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: snappy
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: timecop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: A Kafka (http://kafka.apache.org/) producer and consumer
84
+ email:
85
+ - bobby.potter@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - .rspec
92
+ - .travis.yml
93
+ - .yardopts
94
+ - CHANGES.md
95
+ - Gemfile
96
+ - LICENSE.txt
97
+ - README.md
98
+ - Rakefile
99
+ - TODO.md
100
+ - examples/consumer.rb
101
+ - examples/producer.rb
102
+ - lib/poseidon.rb
103
+ - lib/poseidon/broker_pool.rb
104
+ - lib/poseidon/cluster_metadata.rb
105
+ - lib/poseidon/compressed_value.rb
106
+ - lib/poseidon/compression.rb
107
+ - lib/poseidon/compression/gzip_codec.rb
108
+ - lib/poseidon/compression/snappy_codec.rb
109
+ - lib/poseidon/connection.rb
110
+ - lib/poseidon/fetched_message.rb
111
+ - lib/poseidon/message.rb
112
+ - lib/poseidon/message_conductor.rb
113
+ - lib/poseidon/message_set.rb
114
+ - lib/poseidon/message_to_send.rb
115
+ - lib/poseidon/messages_for_broker.rb
116
+ - lib/poseidon/messages_to_send.rb
117
+ - lib/poseidon/messages_to_send_batch.rb
118
+ - lib/poseidon/partition_consumer.rb
119
+ - lib/poseidon/producer.rb
120
+ - lib/poseidon/producer_compression_config.rb
121
+ - lib/poseidon/protocol.rb
122
+ - lib/poseidon/protocol/protocol_struct.rb
123
+ - lib/poseidon/protocol/request_buffer.rb
124
+ - lib/poseidon/protocol/response_buffer.rb
125
+ - lib/poseidon/sync_producer.rb
126
+ - lib/poseidon/topic_metadata.rb
127
+ - lib/poseidon/version.rb
128
+ - log/.gitkeep
129
+ - poseidon.gemspec
130
+ - spec/integration/multiple_brokers/consumer_spec.rb
131
+ - spec/integration/multiple_brokers/metadata_failures_spec.rb
132
+ - spec/integration/multiple_brokers/rebalance_spec.rb
133
+ - spec/integration/multiple_brokers/round_robin_spec.rb
134
+ - spec/integration/multiple_brokers/spec_helper.rb
135
+ - spec/integration/simple/compression_spec.rb
136
+ - spec/integration/simple/connection_spec.rb
137
+ - spec/integration/simple/multiple_brokers_spec.rb
138
+ - spec/integration/simple/simple_producer_and_consumer_spec.rb
139
+ - spec/integration/simple/spec_helper.rb
140
+ - spec/integration/simple/truncated_messages_spec.rb
141
+ - spec/integration/simple/unavailable_broker_spec.rb
142
+ - spec/spec_helper.rb
143
+ - spec/test_cluster.rb
144
+ - spec/unit/broker_pool_spec.rb
145
+ - spec/unit/cluster_metadata_spec.rb
146
+ - spec/unit/compression/gzip_codec_spec.rb
147
+ - spec/unit/compression/snappy_codec_spec.rb
148
+ - spec/unit/compression_spec.rb
149
+ - spec/unit/connection_spec.rb
150
+ - spec/unit/fetched_message_spec.rb
151
+ - spec/unit/message_conductor_spec.rb
152
+ - spec/unit/message_set_spec.rb
153
+ - spec/unit/message_spec.rb
154
+ - spec/unit/message_to_send_spec.rb
155
+ - spec/unit/messages_for_broker_spec.rb
156
+ - spec/unit/messages_to_send_batch_spec.rb
157
+ - spec/unit/messages_to_send_spec.rb
158
+ - spec/unit/partition_consumer_spec.rb
159
+ - spec/unit/producer_compression_config_spec.rb
160
+ - spec/unit/producer_spec.rb
161
+ - spec/unit/protocol/request_buffer_spec.rb
162
+ - spec/unit/protocol_spec.rb
163
+ - spec/unit/sync_producer_spec.rb
164
+ - spec/unit/topic_metadata_spec.rb
165
+ homepage: https://github.com/bpot/poseidon
166
+ licenses:
167
+ - MIT
168
+ metadata: {}
169
+ post_install_message:
170
+ rdoc_options: []
171
+ require_paths:
172
+ - lib
173
+ required_ruby_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - '>='
176
+ - !ruby/object:Gem::Version
177
+ version: 1.9.3
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - '>='
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ requirements: []
184
+ rubyforge_project:
185
+ rubygems_version: 2.0.3
186
+ signing_key:
187
+ specification_version: 4
188
+ summary: Poseidon is a producer and consumer implementation for Kafka >= 0.8
189
+ test_files:
190
+ - spec/integration/multiple_brokers/consumer_spec.rb
191
+ - spec/integration/multiple_brokers/metadata_failures_spec.rb
192
+ - spec/integration/multiple_brokers/rebalance_spec.rb
193
+ - spec/integration/multiple_brokers/round_robin_spec.rb
194
+ - spec/integration/multiple_brokers/spec_helper.rb
195
+ - spec/integration/simple/compression_spec.rb
196
+ - spec/integration/simple/connection_spec.rb
197
+ - spec/integration/simple/multiple_brokers_spec.rb
198
+ - spec/integration/simple/simple_producer_and_consumer_spec.rb
199
+ - spec/integration/simple/spec_helper.rb
200
+ - spec/integration/simple/truncated_messages_spec.rb
201
+ - spec/integration/simple/unavailable_broker_spec.rb
202
+ - spec/spec_helper.rb
203
+ - spec/test_cluster.rb
204
+ - spec/unit/broker_pool_spec.rb
205
+ - spec/unit/cluster_metadata_spec.rb
206
+ - spec/unit/compression/gzip_codec_spec.rb
207
+ - spec/unit/compression/snappy_codec_spec.rb
208
+ - spec/unit/compression_spec.rb
209
+ - spec/unit/connection_spec.rb
210
+ - spec/unit/fetched_message_spec.rb
211
+ - spec/unit/message_conductor_spec.rb
212
+ - spec/unit/message_set_spec.rb
213
+ - spec/unit/message_spec.rb
214
+ - spec/unit/message_to_send_spec.rb
215
+ - spec/unit/messages_for_broker_spec.rb
216
+ - spec/unit/messages_to_send_batch_spec.rb
217
+ - spec/unit/messages_to_send_spec.rb
218
+ - spec/unit/partition_consumer_spec.rb
219
+ - spec/unit/producer_compression_config_spec.rb
220
+ - spec/unit/producer_spec.rb
221
+ - spec/unit/protocol/request_buffer_spec.rb
222
+ - spec/unit/protocol_spec.rb
223
+ - spec/unit/sync_producer_spec.rb
224
+ - spec/unit/topic_metadata_spec.rb
225
+ has_rdoc: