codeclimate-poseidon 0.0.8

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