poseidon 0.0.3 → 0.0.4
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.
- 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
|