ld-eventsource 2.1.1 → 2.2.0
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/lib/ld-eventsource/client.rb +6 -3
- data/lib/ld-eventsource/events.rb +5 -1
- data/lib/ld-eventsource/impl/backoff.rb +5 -1
- data/lib/ld-eventsource/impl/buffered_line_reader.rb +13 -4
- data/lib/ld-eventsource/impl/event_parser.rb +7 -3
- data/lib/ld-eventsource/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76ed80d3fefe60b6a147769dc1b44b0dfd7fe5b6841ff84655ae86764def70b9
|
4
|
+
data.tar.gz: cf24cff61716e4487d74023e09be18a516232a198aabcda2742fb8ec8de9de72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 329c044114376d9d618e37a138b7c99dc5c4f00baa3d22ea72ce88309deec8bd22a62c0513a362223542f9ddfa5aaae0413e14bbf336ef943a90e0374d2d9c89
|
7
|
+
data.tar.gz: 9110b5daa08a3c7fb04bb432527feaf4bee5e67d02b215621c89546ffd0a4da98c14a9618cdf4040474afe1649db777996547bfb502512930a3b364f05dd57c1
|
@@ -306,6 +306,9 @@ module SSE
|
|
306
306
|
else
|
307
307
|
begin
|
308
308
|
data = cxn.readpartial
|
309
|
+
# readpartial gives us a string, which may not be a valid UTF-8 string because a
|
310
|
+
# multi-byte character might not yet have been fully read, but BufferedLineReader
|
311
|
+
# will handle that.
|
309
312
|
rescue HTTP::TimeoutError
|
310
313
|
# For historical reasons, we rethrow this as our own type
|
311
314
|
raise Errors::ReadTimeoutError.new(@read_timeout)
|
@@ -315,7 +318,7 @@ module SSE
|
|
315
318
|
end
|
316
319
|
end
|
317
320
|
end
|
318
|
-
event_parser = Impl::EventParser.new(Impl::BufferedLineReader.lines_from(chunks))
|
321
|
+
event_parser = Impl::EventParser.new(Impl::BufferedLineReader.lines_from(chunks), @last_id)
|
319
322
|
|
320
323
|
event_parser.items.each do |item|
|
321
324
|
return if @stopped.value
|
@@ -331,7 +334,7 @@ module SSE
|
|
331
334
|
|
332
335
|
def dispatch_event(event)
|
333
336
|
@logger.debug { "Received event: #{event}" }
|
334
|
-
@last_id = event.id
|
337
|
+
@last_id = event.id if !event.id.nil?
|
335
338
|
|
336
339
|
# Pass the event to the caller
|
337
340
|
@on[:event].call(event)
|
@@ -354,7 +357,7 @@ module SSE
|
|
354
357
|
'Cache-Control' => 'no-cache',
|
355
358
|
'User-Agent' => 'ruby-eventsource'
|
356
359
|
}
|
357
|
-
h['Last-Event-Id'] = @last_id if !@last_id.nil?
|
360
|
+
h['Last-Event-Id'] = @last_id if !@last_id.nil? && @last_id != ""
|
358
361
|
h.merge(@headers)
|
359
362
|
end
|
360
363
|
end
|
@@ -11,6 +11,10 @@ module SSE
|
|
11
11
|
# if there were multiple `data:` lines, they are concatenated with newlines
|
12
12
|
# @!attribute id
|
13
13
|
# @return [String] the string that appeared after `id:` in the stream if any, or nil
|
14
|
+
# @!attribute last_event_id
|
15
|
+
# @return [String] the `id:` value that was most recently seen in an event from
|
16
|
+
# this stream; this differs from the `id` property in that it retains the same value
|
17
|
+
# in subsequent events if they do not provide their own `id:`
|
14
18
|
#
|
15
|
-
StreamEvent = Struct.new(:type, :data, :id)
|
19
|
+
StreamEvent = Struct.new(:type, :data, :id, :last_event_id)
|
16
20
|
end
|
@@ -41,7 +41,11 @@ module SSE
|
|
41
41
|
@last_good_time = nil
|
42
42
|
target = ([@base_interval * (2 ** @attempts), @max_interval].min).to_f
|
43
43
|
@attempts += 1
|
44
|
-
|
44
|
+
if target == 0
|
45
|
+
0 # in some Ruby versions it's illegal to call rand(0)
|
46
|
+
else
|
47
|
+
(target / 2) + @jitter_rand.rand(target / 2)
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
#
|
@@ -9,17 +9,21 @@ module SSE
|
|
9
9
|
# input data runs out, the output enumerator ends and does not include any partially
|
10
10
|
# completed line.
|
11
11
|
#
|
12
|
-
# @param [Enumerator] chunks an enumerator that will yield strings from a stream
|
13
|
-
#
|
12
|
+
# @param [Enumerator] chunks an enumerator that will yield strings from a stream -
|
13
|
+
# these are treated as raw UTF-8 bytes, regardless of the string's declared encoding
|
14
|
+
# (so it is OK if a multi-byte character is split across chunks); if the declared
|
15
|
+
# encoding of the chunk is not ASCII-8BIT, it will be changed to ASCII-8BIT in place
|
16
|
+
# @return [Enumerator] an enumerator that will yield one line at a time in UTF-8
|
14
17
|
#
|
15
18
|
def self.lines_from(chunks)
|
16
|
-
buffer = ""
|
19
|
+
buffer = "".b
|
17
20
|
position = 0
|
18
21
|
line_start = 0
|
19
22
|
last_char_was_cr = false
|
20
23
|
|
21
24
|
Enumerator.new do |gen|
|
22
25
|
chunks.each do |chunk|
|
26
|
+
chunk.force_encoding("ASCII-8BIT")
|
23
27
|
buffer << chunk
|
24
28
|
|
25
29
|
loop do
|
@@ -47,7 +51,12 @@ module SSE
|
|
47
51
|
next
|
48
52
|
end
|
49
53
|
|
50
|
-
line = buffer[line_start, i - line_start]
|
54
|
+
line = buffer[line_start, i - line_start].force_encoding("UTF-8")
|
55
|
+
# Calling force_encoding just declares that we believe the encoding of this string to be
|
56
|
+
# UTF-8 (which is the only encoding allowed in the SSE protocol); it doesn't cause any
|
57
|
+
# re-decoding of the string. The previous line-parsing steps were done on raw 8-bit
|
58
|
+
# strings so that it won't try to do any UTF-8 decoding on intermediate slices.
|
59
|
+
|
51
60
|
last_char_was_cr = false
|
52
61
|
i += 1
|
53
62
|
if ch == "\r"
|
@@ -23,8 +23,9 @@ module SSE
|
|
23
23
|
# @param [Enumerator] lines an enumerator that will yield one line of text at a time;
|
24
24
|
# the lines should not include line terminators
|
25
25
|
#
|
26
|
-
def initialize(lines)
|
26
|
+
def initialize(lines, last_event_id = nil)
|
27
27
|
@lines = lines
|
28
|
+
@last_event_id = last_event_id
|
28
29
|
reset_buffers
|
29
30
|
end
|
30
31
|
|
@@ -65,7 +66,10 @@ module SSE
|
|
65
66
|
@data << value
|
66
67
|
@have_data = true
|
67
68
|
when "id"
|
68
|
-
|
69
|
+
if !value.include?("\x00")
|
70
|
+
@id = value
|
71
|
+
@last_event_id = value
|
72
|
+
end
|
69
73
|
when "retry"
|
70
74
|
if /^(?<num>\d+)$/ =~ value
|
71
75
|
return SetRetryInterval.new(num.to_i)
|
@@ -76,7 +80,7 @@ module SSE
|
|
76
80
|
|
77
81
|
def maybe_create_event
|
78
82
|
return nil if !@have_data
|
79
|
-
StreamEvent.new(@type || :message, @data, @id)
|
83
|
+
StreamEvent.new(@type || :message, @data, @id, @last_event_id)
|
80
84
|
end
|
81
85
|
end
|
82
86
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ld-eventsource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LaunchDarkly
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
136
|
- !ruby/object:Gem::Version
|
137
137
|
version: '0'
|
138
138
|
requirements: []
|
139
|
-
rubygems_version: 3.
|
139
|
+
rubygems_version: 3.3.4
|
140
140
|
signing_key:
|
141
141
|
specification_version: 4
|
142
142
|
summary: LaunchDarkly SSE client
|