ld-celluloid-eventsource 0.5.0 → 0.8.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/ld-celluloid-eventsource.gemspec +3 -2
- data/lib/{celluloid → ld_celluloid_eventsource}/eventsource.rb +77 -38
- data/lib/{celluloid/eventsource → ld_celluloid_eventsource}/response_parser.rb +0 -0
- data/lib/{celluloid/eventsource → ld_celluloid_eventsource}/version.rb +1 -1
- metadata +43 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8be57755b8e9109f162424b0bfc717494646820b
|
4
|
+
data.tar.gz: 4e99b0dfcca684ffc8b7f5404834c76dbf2bbc60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ba0c333067e2bcb0eda60c5df2d73bf75112bbc80f776f09cc33febd7700d977c034552c3fafad7daa4f7fb35b8277d8ffaf3f4f5238dc7b5644d6fc5d093dc
|
7
|
+
data.tar.gz: 3066e8834456d81e6f3a8191d922331e313f18f21522b9a0bfc39560eeb372734b1f518aa13a641edacf0d3ace029649139cf55f611ddd3b11fecc06067ad7b3
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require '
|
4
|
+
require 'ld_celluloid_eventsource/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "ld-celluloid-eventsource"
|
@@ -20,8 +20,9 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency 'celluloid-io', '~> 0.17.3'
|
22
22
|
spec.add_dependency 'http_parser.rb', '~> 0.6.0'
|
23
|
+
spec.add_dependency 'concurrent-ruby', '~> 1.0.4'
|
24
|
+
spec.add_dependency 'retries', '~> 0.0.5'
|
23
25
|
|
24
|
-
spec.add_development_dependency 'atomic', '~> 1.1'
|
25
26
|
spec.add_development_dependency "rspec", '~> 3.0'
|
26
27
|
spec.add_development_dependency "bundler", "~> 1.7"
|
27
28
|
spec.add_development_dependency "rake", '~> 10.1'
|
@@ -2,19 +2,26 @@ require 'celluloid/current'
|
|
2
2
|
require "celluloid/eventsource/version"
|
3
3
|
require 'celluloid/io'
|
4
4
|
require 'celluloid/eventsource/response_parser'
|
5
|
+
require 'concurrent'
|
6
|
+
require 'logger'
|
7
|
+
require 'retries'
|
5
8
|
require 'uri'
|
6
9
|
|
7
10
|
module Celluloid
|
8
11
|
class EventSource
|
9
12
|
include Celluloid::IO
|
10
13
|
|
11
|
-
attr_reader :url, :with_credentials
|
14
|
+
attr_reader :url, :with_credentials, :heartbeat_timeout, :logger
|
12
15
|
attr_reader :ready_state
|
13
16
|
|
14
17
|
CONNECTING = 0
|
15
18
|
OPEN = 1
|
16
19
|
CLOSED = 2
|
17
20
|
|
21
|
+
# 2^31 since our retries library doesn't allow for unlimited retries.
|
22
|
+
# At an average of 1 second per retry, we'll still be retrying in 68 years.
|
23
|
+
MAX_RETRIES = 2147483648
|
24
|
+
|
18
25
|
execute_block_on_receiver :initialize
|
19
26
|
|
20
27
|
def initialize(uri, options = {})
|
@@ -22,6 +29,9 @@ module Celluloid
|
|
22
29
|
options = options.dup
|
23
30
|
@ready_state = CONNECTING
|
24
31
|
@with_credentials = options.delete(:with_credentials) { false }
|
32
|
+
@heartbeat_timeout = options.delete(:heartbeat_timeout) { 300 }
|
33
|
+
@logger = options.delete(:logger) { default_logger }
|
34
|
+
@logger.info("[EventSource] Starting client connecting to url: #{self.url} with heartbeat timeout: #{@heartbeat_timeout} seconds")
|
25
35
|
@headers = default_request_headers.merge(options.fetch(:headers, {}))
|
26
36
|
|
27
37
|
@event_type_buffer = ""
|
@@ -31,7 +41,7 @@ module Celluloid
|
|
31
41
|
@last_event_id = String.new
|
32
42
|
|
33
43
|
@reconnect_timeout = 1
|
34
|
-
@on = { open: ->{}, message: ->(_) {}
|
44
|
+
@on = { open: ->{}, message: ->(_) {}}
|
35
45
|
@parser = ResponseParser.new
|
36
46
|
|
37
47
|
@chunked = false
|
@@ -58,14 +68,25 @@ module Celluloid
|
|
58
68
|
begin
|
59
69
|
establish_connection
|
60
70
|
chunked? ? process_chunked_stream : process_stream
|
61
|
-
rescue
|
62
|
-
|
71
|
+
rescue Exception => e
|
72
|
+
logger.debug("[EventSource] Reconnecting after exception: #{e}")
|
63
73
|
end
|
64
|
-
sleep @reconnect_timeout
|
74
|
+
sleep @reconnect_timeout
|
65
75
|
end
|
66
76
|
end
|
67
77
|
|
78
|
+
def listen_for_heartbeats
|
79
|
+
@logger.debug("[EventSource] Starting listening for heartbeats. Reconnecting after #{@heartbeat_timeout} seconds if no comments are received")
|
80
|
+
@heartbeat_task.cancel if @heartbeat_task
|
81
|
+
@heartbeat_task = Concurrent::ScheduledTask.new(@heartbeat_timeout){
|
82
|
+
@logger.warn("[EventSource] Didn't get heartbeat after #{@heartbeat_timeout} seconds. Reconnecting.")
|
83
|
+
@socket.close if @socket
|
84
|
+
}.execute
|
85
|
+
end
|
86
|
+
|
68
87
|
def close
|
88
|
+
@logger.info("[EventSource] Closing client")
|
89
|
+
@heartbeat_task.cancel if @heartbeat_task
|
69
90
|
@socket.close if @socket
|
70
91
|
@ready_state = CLOSED
|
71
92
|
end
|
@@ -82,10 +103,6 @@ module Celluloid
|
|
82
103
|
@on[:message] = action
|
83
104
|
end
|
84
105
|
|
85
|
-
def on_error(&action)
|
86
|
-
@on[:error] = action
|
87
|
-
end
|
88
|
-
|
89
106
|
private
|
90
107
|
|
91
108
|
MessageEvent = Struct.new(:type, :data, :last_event_id)
|
@@ -95,31 +112,38 @@ module Celluloid
|
|
95
112
|
end
|
96
113
|
|
97
114
|
def establish_connection
|
98
|
-
|
99
|
-
|
100
|
-
if ssl?
|
101
|
-
@socket = Celluloid::IO::SSLSocket.new(@socket)
|
102
|
-
@socket.connect
|
115
|
+
handler = Proc.new do |exception, attempt_number, total_delay|
|
116
|
+
logger.warn("[EventSource] Could not connect with exception: #{exception.class} #{exception.message}; retry attempt #{attempt_number}; #{total_delay} seconds have passed.")
|
103
117
|
end
|
104
118
|
|
105
|
-
|
119
|
+
with_retries(:max_tries => MAX_RETRIES,
|
120
|
+
:base_sleep_seconds => 1.0,
|
121
|
+
:max_sleep_seconds => 30.0,
|
122
|
+
:handler => handler,
|
123
|
+
:rescue => Exception) do
|
124
|
+
if !closed?
|
125
|
+
@logger.info("[EventSource] Connecting to url: #{@url}")
|
126
|
+
@socket = Celluloid::IO::TCPSocket.new(@url.host, @url.port)
|
106
127
|
|
107
|
-
|
108
|
-
|
109
|
-
|
128
|
+
if ssl?
|
129
|
+
@socket = Celluloid::IO::SSLSocket.new(@socket)
|
130
|
+
@socket.connect
|
131
|
+
end
|
132
|
+
|
133
|
+
@socket.write(request_string)
|
134
|
+
|
135
|
+
until @parser.headers?
|
136
|
+
@parser << @socket.readline
|
137
|
+
end
|
110
138
|
|
111
|
-
|
112
|
-
|
113
|
-
|
139
|
+
if @parser.status_code != 200
|
140
|
+
@socket.close if @socket
|
141
|
+
raise "[EventSource] Could not connect to stream. Got status code: #{@parser.status_code}"
|
142
|
+
end
|
143
|
+
|
144
|
+
handle_headers(@parser.headers)
|
114
145
|
end
|
115
|
-
# If the server returns a non-200, we don't want to close-- we just want to
|
116
|
-
# report an error
|
117
|
-
# close
|
118
|
-
@on[:error].call({status_code: @parser.status_code, body: @parser.chunk})
|
119
|
-
return
|
120
146
|
end
|
121
|
-
|
122
|
-
handle_headers(@parser.headers)
|
123
147
|
end
|
124
148
|
|
125
149
|
def default_request_headers
|
@@ -176,14 +200,16 @@ module Celluloid
|
|
176
200
|
|
177
201
|
def parse_line(line)
|
178
202
|
case line
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
203
|
+
when /^: ?(.*)$/
|
204
|
+
@logger.debug("[EventSource] Got comment: #{$1}")
|
205
|
+
listen_for_heartbeats
|
206
|
+
when /^(\w+): ?(.*)$/
|
207
|
+
process_field($1, $2)
|
208
|
+
else
|
209
|
+
if chunked? && !@data_buffer.empty?
|
210
|
+
@data_buffer.rstrip!
|
211
|
+
process_field("data", line.rstrip)
|
212
|
+
end
|
187
213
|
end
|
188
214
|
end
|
189
215
|
|
@@ -196,6 +222,7 @@ module Celluloid
|
|
196
222
|
event = MessageEvent.new(:message, @data_buffer, @last_event_id)
|
197
223
|
event.type = @event_type_buffer.to_sym unless @event_type_buffer.empty?
|
198
224
|
|
225
|
+
@logger.debug("[EventSource] Dispatching event: #{event}")
|
199
226
|
dispatch_event(event)
|
200
227
|
ensure
|
201
228
|
clear_buffers!
|
@@ -221,9 +248,11 @@ module Celluloid
|
|
221
248
|
@chunked = !headers["Transfer-Encoding"].nil? && headers["Transfer-Encoding"].include?("chunked")
|
222
249
|
@ready_state = OPEN
|
223
250
|
@on[:open].call
|
251
|
+
@logger.info("[EventSource] Connected ok!")
|
252
|
+
listen_for_heartbeats
|
224
253
|
else
|
225
|
-
close
|
226
|
-
|
254
|
+
@socket.close if @socket
|
255
|
+
raise "Got invalid Content-Type header: #{headers['Content-Type']}. Expected text/event-stream"
|
227
256
|
end
|
228
257
|
end
|
229
258
|
|
@@ -233,6 +262,16 @@ module Celluloid
|
|
233
262
|
["GET #{url.request_uri} HTTP/1.1", headers].flatten.join("\r\n").concat("\r\n\r\n")
|
234
263
|
end
|
235
264
|
|
265
|
+
def default_logger
|
266
|
+
if defined?(Rails) && Rails.respond_to?(:logger)
|
267
|
+
Rails.logger
|
268
|
+
else
|
269
|
+
log = ::Logger.new($stdout)
|
270
|
+
log.level = ::Logger::INFO
|
271
|
+
log
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
236
275
|
end
|
237
276
|
|
238
277
|
end
|
File without changes
|
metadata
CHANGED
@@ -1,111 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ld-celluloid-eventsource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leo Correa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: celluloid-io
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 0.17.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.17.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: http_parser.rb
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 0.6.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.6.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: concurrent-ruby
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
48
|
-
type: :
|
47
|
+
version: 1.0.4
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.4
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: retries
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.0.5
|
62
|
+
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- - ~>
|
66
|
+
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
68
|
+
version: 0.0.5
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rspec
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- - ~>
|
73
|
+
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '3.0'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- - ~>
|
80
|
+
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '3.0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: bundler
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- - ~>
|
87
|
+
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: '1.7'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- - ~>
|
94
|
+
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '1.7'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rake
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- - ~>
|
101
|
+
- - "~>"
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: '10.1'
|
90
104
|
type: :development
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
|
-
- - ~>
|
108
|
+
- - "~>"
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '10.1'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: pry
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
|
-
- - ~>
|
115
|
+
- - "~>"
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: '0.9'
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
|
-
- - ~>
|
122
|
+
- - "~>"
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0.9'
|
111
125
|
description: Celluloid::IO based library to consume Server-Sent Events. This library
|
@@ -116,17 +130,17 @@ executables: []
|
|
116
130
|
extensions: []
|
117
131
|
extra_rdoc_files: []
|
118
132
|
files:
|
119
|
-
- .gitignore
|
120
|
-
- .rspec
|
121
|
-
- .travis.yml
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".travis.yml"
|
122
136
|
- Gemfile
|
123
137
|
- LICENSE
|
124
138
|
- README.md
|
125
139
|
- Rakefile
|
126
140
|
- ld-celluloid-eventsource.gemspec
|
127
|
-
- lib/
|
128
|
-
- lib/
|
129
|
-
- lib/
|
141
|
+
- lib/ld_celluloid_eventsource/eventsource.rb
|
142
|
+
- lib/ld_celluloid_eventsource/response_parser.rb
|
143
|
+
- lib/ld_celluloid_eventsource/version.rb
|
130
144
|
- log/.gitignore
|
131
145
|
- spec/celluloid/eventsource/response_parser_spec.rb
|
132
146
|
- spec/celluloid/eventsource_spec.rb
|
@@ -143,17 +157,17 @@ require_paths:
|
|
143
157
|
- lib
|
144
158
|
required_ruby_version: !ruby/object:Gem::Requirement
|
145
159
|
requirements:
|
146
|
-
- -
|
160
|
+
- - ">="
|
147
161
|
- !ruby/object:Gem::Version
|
148
162
|
version: '0'
|
149
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
164
|
requirements:
|
151
|
-
- -
|
165
|
+
- - ">="
|
152
166
|
- !ruby/object:Gem::Version
|
153
167
|
version: '0'
|
154
168
|
requirements: []
|
155
169
|
rubyforge_project:
|
156
|
-
rubygems_version: 2.5.
|
170
|
+
rubygems_version: 2.5.1
|
157
171
|
signing_key:
|
158
172
|
specification_version: 4
|
159
173
|
summary: ld-celluloid-eventsource is a gem to consume SSE streaming API.
|