poseidon 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +5 -0
- data/lib/poseidon/connection.rb +1 -1
- data/lib/poseidon/partition_consumer.rb +7 -3
- data/lib/poseidon/protocol/protocol_struct.rb +19 -1
- data/lib/poseidon/protocol/request_buffer.rb +5 -5
- data/lib/poseidon/protocol/response_buffer.rb +2 -2
- data/lib/poseidon/version.rb +1 -1
- data/spec/integration/simple/truncated_messages_spec.rb +44 -0
- data/spec/unit/message_conductor_spec.rb +6 -2
- data/spec/unit/message_spec.rb +17 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c4852d5b615cd1fe50528b0136602756087d0db
|
4
|
+
data.tar.gz: 2172c5cd70c8047cb0b0bdd171d5f9ed5cb82b73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3949ab96ce033255e31bc588db0f0895c6a72a91d9bfb56137995f0d5f52bc467dfa660359d440fddca89fe64fd3f6af7a2b28f2476698ba35319f999358a721
|
7
|
+
data.tar.gz: 2348e329e244a3b4a777e8635143d33ec591c10ee411f40aa69a629487643585e8b303c13f120d51e85a2dde13f5dea5b0cb3290b152e619d3fa07dc6f4769d4
|
data/CHANGES.md
CHANGED
data/lib/poseidon/connection.rb
CHANGED
@@ -115,7 +115,7 @@ module Poseidon
|
|
115
115
|
def send_request(request)
|
116
116
|
buffer = Protocol::RequestBuffer.new
|
117
117
|
request.write(buffer)
|
118
|
-
@socket.write([buffer.to_s.
|
118
|
+
@socket.write([buffer.to_s.bytesize].pack("N") + buffer.to_s)
|
119
119
|
rescue Errno::EPIPE, Errno::ECONNRESET
|
120
120
|
@socket = nil
|
121
121
|
raise ConnectionFailedError
|
@@ -82,9 +82,13 @@ module Poseidon
|
|
82
82
|
#
|
83
83
|
# @api public
|
84
84
|
def fetch(options = {})
|
85
|
-
fetch_max_wait = options
|
86
|
-
fetch_max_bytes = options
|
87
|
-
fetch_min_bytes = options
|
85
|
+
fetch_max_wait = options.delete(:max_wait) || max_wait_ms
|
86
|
+
fetch_max_bytes = options.delete(:max_bytes) || max_bytes
|
87
|
+
fetch_min_bytes = options.delete(:min_bytes) || min_bytes
|
88
|
+
|
89
|
+
if options.keys.any?
|
90
|
+
raise ArgumentError, "Unknown options: #{options.keys.inspect}"
|
91
|
+
end
|
88
92
|
|
89
93
|
topic_fetches = build_topic_fetch_request(fetch_max_bytes)
|
90
94
|
fetch_response = @connection.fetch(fetch_max_wait, fetch_min_bytes, topic_fetches)
|
@@ -158,6 +158,11 @@ module Poseidon
|
|
158
158
|
|
159
159
|
def read(buffer)
|
160
160
|
if self.class.prepend_size?
|
161
|
+
if !have_header?(buffer)
|
162
|
+
@truncated = true
|
163
|
+
return
|
164
|
+
end
|
165
|
+
|
161
166
|
@size = buffer.int32
|
162
167
|
|
163
168
|
if self.class.prepend_crc32?
|
@@ -171,7 +176,6 @@ module Poseidon
|
|
171
176
|
expected_bytes_remaining = @size
|
172
177
|
end
|
173
178
|
|
174
|
-
|
175
179
|
if self.class.truncatable? && expected_bytes_remaining > buffer.bytes_remaining
|
176
180
|
@truncated = true
|
177
181
|
return
|
@@ -190,6 +194,20 @@ module Poseidon
|
|
190
194
|
end
|
191
195
|
end
|
192
196
|
|
197
|
+
def have_header?(buffer)
|
198
|
+
if self.class.truncatable?
|
199
|
+
if self.class.prepend_crc32?
|
200
|
+
header_bytes = 8
|
201
|
+
else
|
202
|
+
header_bytes = 4
|
203
|
+
end
|
204
|
+
|
205
|
+
return buffer.bytes_remaining >= header_bytes
|
206
|
+
else
|
207
|
+
return true
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
193
211
|
def read_member(buffer, member)
|
194
212
|
case type = type_map[member]
|
195
213
|
when Array
|
@@ -40,7 +40,7 @@ module Poseidon
|
|
40
40
|
if string.nil?
|
41
41
|
int16(-1)
|
42
42
|
else
|
43
|
-
int16(string.
|
43
|
+
int16(string.bytesize)
|
44
44
|
append(string)
|
45
45
|
end
|
46
46
|
end
|
@@ -49,13 +49,13 @@ module Poseidon
|
|
49
49
|
if string.nil?
|
50
50
|
int32(-1)
|
51
51
|
else
|
52
|
-
int32(string.
|
52
|
+
int32(string.bytesize)
|
53
53
|
append(string)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
57
|
def prepend_crc32
|
58
|
-
checksum_pos = @s.
|
58
|
+
checksum_pos = @s.bytesize
|
59
59
|
@s += " "
|
60
60
|
yield
|
61
61
|
@s[checksum_pos] = [Zlib::crc32(@s[(checksum_pos+1)..-1])].pack("N")
|
@@ -63,10 +63,10 @@ module Poseidon
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def prepend_size
|
66
|
-
size_pos = @s.
|
66
|
+
size_pos = @s.bytesize
|
67
67
|
@s += " "
|
68
68
|
yield
|
69
|
-
@s[size_pos] = [(@s.
|
69
|
+
@s[size_pos] = [(@s.bytesize-1) - size_pos].pack("N")
|
70
70
|
nil
|
71
71
|
end
|
72
72
|
|
data/lib/poseidon/version.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'integration/simple/spec_helper'
|
2
|
+
|
3
|
+
describe "truncated messages" do
|
4
|
+
before(:all) do
|
5
|
+
@s1 = "a" * 335
|
6
|
+
@s2 = "b" * 338
|
7
|
+
|
8
|
+
@producer = Producer.new(["localhost:9092"],
|
9
|
+
"test_client",
|
10
|
+
:type => :sync)
|
11
|
+
|
12
|
+
@producer.send_messages([Message.new(:topic => 'test_max_bytes', :value => @s1), Message.new(:topic => 'test_max_bytes', :value => @s2)])
|
13
|
+
end
|
14
|
+
|
15
|
+
it "correctly handles max_byte lengths smallert than a message" do
|
16
|
+
0.upto(360) do |n|
|
17
|
+
consumer = PartitionConsumer.new("test_consumer", "localhost", 9092,
|
18
|
+
"test_max_bytes", 0, :earliest_offset)
|
19
|
+
expect(consumer.fetch(:max_bytes => n)).to eq([])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "correctly handles max_byte lengths that should return a single message" do
|
24
|
+
361.upto(724) do |n|
|
25
|
+
consumer = PartitionConsumer.new("test_consumer", "localhost", 9092,
|
26
|
+
"test_max_bytes", 0, :earliest_offset)
|
27
|
+
|
28
|
+
messages = consumer.fetch(:max_bytes => n)
|
29
|
+
expect(messages.size).to eq(1)
|
30
|
+
expect(messages.first.value).to eq(@s1)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "correctly handles max_byte lengths that should return two messages" do
|
35
|
+
725.upto(1000) do |n|
|
36
|
+
consumer = PartitionConsumer.new("test_consumer", "localhost", 9092,
|
37
|
+
"test_max_bytes", 0, :earliest_offset)
|
38
|
+
|
39
|
+
messages = consumer.fetch(:max_bytes => n)
|
40
|
+
expect(messages.size).to eq(2)
|
41
|
+
expect(messages.map(&:value)).to eq([@s1, @s2])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -24,9 +24,13 @@ describe MessageConductor do
|
|
24
24
|
|
25
25
|
context "for unkeyed messages" do
|
26
26
|
it "round robins which partition the message should go to" do
|
27
|
-
|
28
|
-
|
27
|
+
destinations = 4.times.map do
|
28
|
+
@mc.destination("test").first
|
29
29
|
end
|
30
|
+
|
31
|
+
first = [destinations[0], destinations[2]]
|
32
|
+
second = [destinations[1], destinations[3]]
|
33
|
+
expect([first.uniq, second.uniq].sort).to eq([[0],[1]])
|
30
34
|
end
|
31
35
|
|
32
36
|
context "unknown topic" do
|
data/spec/unit/message_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe Message do
|
@@ -87,6 +88,22 @@ describe Message do
|
|
87
88
|
end
|
88
89
|
end
|
89
90
|
|
91
|
+
context "utf8 string with multibyte characters" do
|
92
|
+
it "roundtrips correctly" do
|
93
|
+
s = "the µ is two bytes"
|
94
|
+
m = Message.new(:value => s,
|
95
|
+
:key => "key",
|
96
|
+
:topic => "topic")
|
97
|
+
|
98
|
+
req_buf = Protocol::RequestBuffer.new
|
99
|
+
m.write(req_buf)
|
100
|
+
|
101
|
+
resp_buf = Protocol::ResponseBuffer.new(req_buf.to_s)
|
102
|
+
|
103
|
+
expect(Message.read(resp_buf).value).to eq(s.force_encoding("ASCII-8BIT"))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
90
107
|
context "frozen string for value" do
|
91
108
|
it "builds the payload without error" do
|
92
109
|
s = "asdffasdf".freeze
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poseidon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Potter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- spec/integration/simple/multiple_brokers_spec.rb
|
122
122
|
- spec/integration/simple/simple_producer_and_consumer_spec.rb
|
123
123
|
- spec/integration/simple/spec_helper.rb
|
124
|
+
- spec/integration/simple/truncated_messages_spec.rb
|
124
125
|
- spec/integration/simple/unavailable_broker_spec.rb
|
125
126
|
- spec/spec_helper.rb
|
126
127
|
- spec/test_cluster.rb
|
@@ -176,6 +177,7 @@ test_files:
|
|
176
177
|
- spec/integration/simple/multiple_brokers_spec.rb
|
177
178
|
- spec/integration/simple/simple_producer_and_consumer_spec.rb
|
178
179
|
- spec/integration/simple/spec_helper.rb
|
180
|
+
- spec/integration/simple/truncated_messages_spec.rb
|
179
181
|
- spec/integration/simple/unavailable_broker_spec.rb
|
180
182
|
- spec/spec_helper.rb
|
181
183
|
- spec/test_cluster.rb
|