deepstream 0.3.1 → 1.0.3
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 +5 -5
- data/README.md +11 -8
- data/deepstream.gemspec +6 -3
- data/lib/deepstream.rb +1 -1
- data/lib/deepstream/ack_timeout_registry.rb +6 -2
- data/lib/deepstream/async_patch.rb +57 -0
- data/lib/deepstream/client.rb +101 -79
- data/lib/deepstream/error_handler.rb +3 -3
- data/lib/deepstream/event_handler.rb +6 -6
- data/lib/deepstream/helpers.rb +4 -8
- data/lib/deepstream/list.rb +7 -1
- data/lib/deepstream/message.rb +10 -4
- data/lib/deepstream/record.rb +22 -4
- data/lib/deepstream/record_handler.rb +12 -4
- metadata +50 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a8cafac8651bd0cb90746e47c290919eb51acb2058e24fd345759ffa0a459996
|
4
|
+
data.tar.gz: 29d4d74d4e417afd703e0ad190b138b7145cf8699cd5bb1c90ca0d006b95b83a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6f1f0bec2528e8fc4694b3febf05a036551fed454277bb3e9d655453805d4e938d51d6bc2a6765ee254739c36d7d6634c03f599659dad25c08ee3907085bafc
|
7
|
+
data.tar.gz: 968a2b71039dda4367e1152acb96f5ff164c5c14f4736774ee408cc7daa8c32f3d7661473f1eb63f9f745e5e7bd1cd024a2917a6f2281662a7e39251d5444e79
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# deepstream-ruby
|
2
2
|
|
3
3
|
deepstream.io ruby client
|
4
|
+
deepstream version >5 needed
|
4
5
|
|
5
6
|
[](http://badge.fury.io/rb/deepstream)
|
6
7
|
[](https://github.com/Currency-One/deepstream-ruby/blob/master/LICENSE)
|
@@ -19,19 +20,16 @@ ds = Deepstream::Client.new('localhost')
|
|
19
20
|
# or
|
20
21
|
ds = Deepstream::Client.new('ws://localhost:6020')
|
21
22
|
# or
|
22
|
-
ds = Deepstream::Client.new('ws://localhost:6020/deepstream',
|
23
|
+
ds = Deepstream::Client.new('ws://localhost:6020/deepstream-v3',
|
23
24
|
ack_timeout: nil, # ACK timeout; if nil, then the client never checks ACK timeout errors
|
24
|
-
autologin: false, # authorise the client when a Websocket connection is initialized; you don't need to call login() then
|
25
25
|
credentials: { username: 'John', password: 'Doe' }, # credentials used to authorise the client
|
26
26
|
heartbeat_interval: nil # when two server heartbeats are missed the client considers the connection to be lost
|
27
|
-
max_reconnect_attempts: nil,
|
28
|
-
max_reconnect_interval: 30, # seconds
|
29
|
-
reconnect_interval: 1, # seconds, the final interval is a lower number from (reconnect_interval * failed_attempts, max_reconnect_interval)
|
30
27
|
emit_timeout: 0, # if 0, then events that failed to be emitted are thrown away
|
31
28
|
# if nil, then events are stored in a buffer, waiting for reconnection
|
32
29
|
# if another number, then events are stored in a buffer and sent if the client reconnects in emit_timeout seconds
|
33
30
|
verbose: false, # show verbose information about connection, incoming and outgoing messages etc.
|
34
|
-
debug: false # use for testing only; if true, any exception will terminate the client
|
31
|
+
debug: false, # use for testing only; if true, any exception will terminate the client
|
32
|
+
in_thread: true # if true, putting client in separated thread
|
35
33
|
)
|
36
34
|
# log in to the server
|
37
35
|
ds.login
|
@@ -84,8 +82,13 @@ foo.all
|
|
84
82
|
```
|
85
83
|
|
86
84
|
|
87
|
-
|
85
|
+
## Development
|
88
86
|
|
89
87
|
```bash
|
90
88
|
git submodule update --init --recursive
|
91
|
-
```
|
89
|
+
```
|
90
|
+
|
91
|
+
|
92
|
+
## To Do
|
93
|
+
|
94
|
+
Adjust tests, to work with new version (without celluloid)
|
data/deepstream.gemspec
CHANGED
@@ -4,9 +4,9 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "deepstream"
|
7
|
-
spec.version = "0.3
|
7
|
+
spec.version = "1.0.3"
|
8
8
|
spec.authors = ["Currency-One S.A."]
|
9
|
-
spec.email = ["
|
9
|
+
spec.email = ["ruby@currency-one.com"]
|
10
10
|
|
11
11
|
spec.summary = %q{deepstream.io ruby client}
|
12
12
|
spec.description = %q{Basic ruby client for the deepstream.io server}
|
@@ -19,7 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
spec.required_ruby_version = '>= 2.3.0'
|
21
21
|
spec.license = "Apache-2.0"
|
22
|
-
spec.add_runtime_dependency '
|
22
|
+
spec.add_runtime_dependency 'async', '~> 1.25.0'
|
23
|
+
spec.add_runtime_dependency 'async-io', '~> 1.29.0'
|
24
|
+
spec.add_runtime_dependency 'async-http', '~> 0.52.1'
|
25
|
+
spec.add_runtime_dependency 'async-websocket', '~> 0.14.0'
|
23
26
|
spec.add_development_dependency 'cucumber'
|
24
27
|
spec.add_development_dependency 'reel'
|
25
28
|
spec.add_development_dependency 'pry'
|
data/lib/deepstream.rb
CHANGED
@@ -7,11 +7,15 @@ module Deepstream
|
|
7
7
|
|
8
8
|
def add(name, message)
|
9
9
|
return unless (timeout = @client.options[:ack_timeout])
|
10
|
-
@timeouts[name] =
|
10
|
+
@timeouts[name] = Thread.new do
|
11
|
+
sleep timeout
|
12
|
+
@client.on_error(message)
|
13
|
+
end
|
11
14
|
end
|
12
15
|
|
13
16
|
def cancel(name)
|
14
|
-
@timeouts.
|
17
|
+
@timeouts[name].exit rescue nil
|
18
|
+
@timeouts.delete(name)
|
15
19
|
end
|
16
20
|
end
|
17
21
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Async
|
2
|
+
module WebSocket
|
3
|
+
class Client < ::Protocol::HTTP::Middleware
|
4
|
+
include ::Protocol::WebSocket::Headers
|
5
|
+
|
6
|
+
def self.open(endpoint, *args, &block)
|
7
|
+
client = self.new(HTTP::Client.new(endpoint, *args), mask: true)
|
8
|
+
|
9
|
+
return client unless block_given?
|
10
|
+
|
11
|
+
begin
|
12
|
+
yield client
|
13
|
+
ensure
|
14
|
+
client.close
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.connect(endpoint, *args, **options, &block)
|
19
|
+
self.open(endpoint, *args) do |client|
|
20
|
+
connection = client.connect(endpoint.path, **options)
|
21
|
+
|
22
|
+
return connection unless block_given?
|
23
|
+
|
24
|
+
begin
|
25
|
+
yield connection
|
26
|
+
ensure
|
27
|
+
connection.close
|
28
|
+
end
|
29
|
+
rescue
|
30
|
+
puts "cant connect to #{endpoint}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Connection < ::Protocol::WebSocket::Connection
|
36
|
+
|
37
|
+
def write(object)
|
38
|
+
super(object)
|
39
|
+
end
|
40
|
+
|
41
|
+
def parse(buffer)
|
42
|
+
buffer
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module Protocol
|
49
|
+
module WebSocket
|
50
|
+
class TextFrame
|
51
|
+
|
52
|
+
def unpack
|
53
|
+
encoded_readed_string = super.encode(Encoding::UTF_8)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/deepstream/client.rb
CHANGED
@@ -1,23 +1,24 @@
|
|
1
1
|
require 'forwardable'
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
require '
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
require 'async'
|
3
|
+
require 'async/io/stream'
|
4
|
+
require 'async/http/endpoint'
|
5
|
+
require 'async/websocket/client'
|
6
|
+
require 'async/logger'
|
7
|
+
require_relative './constants'
|
8
|
+
require_relative './error_handler'
|
9
|
+
require_relative './event_handler'
|
10
|
+
require_relative './record_handler'
|
11
|
+
require_relative './helpers'
|
12
|
+
require_relative './message'
|
13
|
+
require_relative './exceptions'
|
14
|
+
require_relative './async_patch'
|
10
15
|
|
11
16
|
module Deepstream
|
12
17
|
class Client
|
13
18
|
attr_reader :options, :state
|
14
19
|
|
15
|
-
include Celluloid
|
16
|
-
include Celluloid::Internals::Logger
|
17
20
|
extend Forwardable
|
18
21
|
|
19
|
-
execute_block_on_receiver :on, :subscribe, :listen
|
20
|
-
|
21
22
|
def_delegators :@event_handler, :on, :emit, :subscribe, :unsubscribe, :listen, :resubscribe, :unlisten
|
22
23
|
def_delegators :@error_handler, :error, :on_error, :on_exception
|
23
24
|
def_delegators :@record_handler, :get, :get_record, :set, :delete, :discard, :get_list
|
@@ -30,23 +31,22 @@ module Deepstream
|
|
30
31
|
@options = Helpers.default_options.merge!(options)
|
31
32
|
@message_buffer = []
|
32
33
|
@last_hearbeat = nil
|
33
|
-
@challenge_denied,
|
34
|
-
@failed_reconnect_attempts = 0
|
34
|
+
@challenge_denied, @@deliberate_close = false
|
35
35
|
@state = CONNECTION_STATE::CLOSED
|
36
|
-
|
36
|
+
@verbose = @options[:verbose]
|
37
|
+
@log = Async.logger
|
38
|
+
@never_connected_before = true
|
37
39
|
connect
|
38
40
|
end
|
39
41
|
|
40
42
|
def on_open
|
41
|
-
info
|
43
|
+
@log.info "Websocket connection opened" if @verbose
|
42
44
|
@state = CONNECTION_STATE::AWAITING_CONNECTION
|
43
|
-
@connection_requested, @deliberate_close = false
|
44
|
-
@failed_reconnect_attempts = 0
|
45
45
|
end
|
46
46
|
|
47
47
|
def on_message(data)
|
48
48
|
message = Message.new(data)
|
49
|
-
info
|
49
|
+
@log.info "Receiving msg = #{message.inspect}" if @verbose
|
50
50
|
case message.topic
|
51
51
|
when TOPIC::AUTH then authentication_message(message)
|
52
52
|
when TOPIC::CONNECTION then connection_message(message)
|
@@ -54,30 +54,19 @@ module Deepstream
|
|
54
54
|
when TOPIC::ERROR then @error_handler.on_error(message)
|
55
55
|
when TOPIC::RECORD then @record_handler.on_message(message)
|
56
56
|
when TOPIC::RPC then raise(UnknownTopic, 'RPC is currently not implemented.')
|
57
|
+
when nil then nil
|
57
58
|
else raise(UnknownTopic, message)
|
58
59
|
end
|
59
60
|
rescue => e
|
60
61
|
on_exception(e)
|
61
62
|
end
|
62
63
|
|
63
|
-
def on_close(code, reason)
|
64
|
-
info("Websocket connection closed: code - #{code.inspect}, reason - #{reason.inspect}")
|
65
|
-
@state = CONNECTION_STATE::CLOSED
|
66
|
-
reconnect unless @deliberate_close
|
67
|
-
rescue => e
|
68
|
-
on_exception(e)
|
69
|
-
end
|
70
|
-
|
71
64
|
def login(credentials = @options[:credentials])
|
72
|
-
@login_requested = true
|
73
65
|
@options[:credentials] = credentials
|
74
66
|
if @challenge_denied
|
75
67
|
on_error("this client's connection was closed")
|
76
|
-
elsif !connected?
|
77
|
-
async.connect
|
78
68
|
elsif @state == CONNECTION_STATE::AUTHENTICATING
|
79
|
-
@
|
80
|
-
send_message(TOPIC::AUTH, ACTION::REQUEST, @options[:credentials].to_json)
|
69
|
+
send_message(TOPIC::AUTH, ACTION::REQUEST, @options[:credentials].to_json, priority: true)
|
81
70
|
end
|
82
71
|
self
|
83
72
|
rescue => e
|
@@ -87,14 +76,19 @@ module Deepstream
|
|
87
76
|
|
88
77
|
def close
|
89
78
|
return unless connected?
|
90
|
-
@state = CONNECTION_STATE::CLOSED
|
91
79
|
@deliberate_close = true
|
92
|
-
@
|
93
|
-
@connection.terminate
|
80
|
+
log.info 'deliberate closing' if @verbose
|
94
81
|
rescue => e
|
95
82
|
on_exception(e)
|
96
83
|
end
|
97
84
|
|
85
|
+
def reconnect
|
86
|
+
return if connected?
|
87
|
+
@deliberate_close = false
|
88
|
+
@state = CONNECTION_STATE::RECONNECTING
|
89
|
+
@log.info 'Reconnecting' if @verbose
|
90
|
+
end
|
91
|
+
|
98
92
|
def connected?
|
99
93
|
@state != CONNECTION_STATE::CLOSED
|
100
94
|
end
|
@@ -111,26 +105,27 @@ module Deepstream
|
|
111
105
|
"#{self.class} #{@url} | connection state: #{@state}"
|
112
106
|
end
|
113
107
|
|
114
|
-
def send_message(*args)
|
108
|
+
def send_message(*args, **kwargs)
|
115
109
|
message = Message.parse(*args)
|
116
|
-
|
117
|
-
|
118
|
-
|
110
|
+
priority = kwargs[:priority] || false
|
111
|
+
timeout = message.topic == TOPIC::EVENT ? kwargs[:timeout] : nil
|
112
|
+
message.set_timeout(timeout) if timeout
|
113
|
+
return unable_to_send_message(message, priority) if !logged_in? && message.needs_authentication?
|
114
|
+
priority ? @message_buffer.unshift(message) : @message_buffer.push(message)
|
119
115
|
rescue Errno::EPIPE
|
120
|
-
unable_to_send_message(message)
|
116
|
+
unable_to_send_message(message, priority)
|
121
117
|
rescue => e
|
122
118
|
on_exception(e)
|
123
119
|
end
|
124
120
|
|
125
121
|
private
|
126
122
|
|
127
|
-
def unable_to_send_message(message)
|
123
|
+
def unable_to_send_message(message, priority)
|
128
124
|
@state = CONNECTION_STATE::CLOSED if logged_in?
|
129
125
|
unless message.expired?
|
130
|
-
|
131
|
-
|
126
|
+
@log.info("Placing a message #{message.inspect} in the buffer, waiting for authentication") if @verbose
|
127
|
+
priority ? @message_buffer.unshift(message) : @message_buffer.push(message)
|
132
128
|
end
|
133
|
-
async.reconnect if !connected? && !@connection_requested
|
134
129
|
end
|
135
130
|
|
136
131
|
def connection_message(message)
|
@@ -160,7 +155,9 @@ module Deepstream
|
|
160
155
|
|
161
156
|
def on_connection_ack
|
162
157
|
@state = CONNECTION_STATE::AUTHENTICATING
|
163
|
-
|
158
|
+
@message_buffer.delete_if { |msg| msg.action == ACTION::PATCH }
|
159
|
+
@record_handler.reinitialize unless @never_connected_before
|
160
|
+
login
|
164
161
|
end
|
165
162
|
|
166
163
|
def on_ping
|
@@ -169,15 +166,22 @@ module Deepstream
|
|
169
166
|
end
|
170
167
|
|
171
168
|
def on_login
|
169
|
+
@never_connected_before = false
|
172
170
|
@state = CONNECTION_STATE::OPEN
|
173
|
-
@message_buffer.each { |message| send_message(message) unless message.expired? }.clear
|
174
171
|
every(@options[:heartbeat_interval]) { check_heartbeat } if @options[:heartbeat_interval]
|
175
172
|
resubscribe
|
176
173
|
end
|
177
174
|
|
178
175
|
def on_rejection
|
179
176
|
@challenge_denied = true
|
180
|
-
|
177
|
+
on_close
|
178
|
+
end
|
179
|
+
|
180
|
+
def on_close
|
181
|
+
@log.info 'Websocket connection closed' if @verbose
|
182
|
+
@state = CONNECTION_STATE::CLOSED
|
183
|
+
rescue => e
|
184
|
+
on_exception(e)
|
181
185
|
end
|
182
186
|
|
183
187
|
def check_heartbeat
|
@@ -187,46 +191,64 @@ module Deepstream
|
|
187
191
|
end
|
188
192
|
|
189
193
|
def on_redirection(message)
|
190
|
-
|
191
|
-
|
194
|
+
on_close
|
195
|
+
@url = message.data.last
|
192
196
|
end
|
193
197
|
|
194
|
-
def connect(
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
@connection_requested = false
|
201
|
-
reraise ? raise : on_exception(e)
|
198
|
+
def connect(in_thread = @options[:in_thread])
|
199
|
+
if in_thread
|
200
|
+
Thread.start { connection_loop }
|
201
|
+
else
|
202
|
+
connection_loop
|
203
|
+
end
|
202
204
|
end
|
203
205
|
|
204
|
-
def
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
206
|
+
def connection_loop
|
207
|
+
Async do |task|
|
208
|
+
@task = task
|
209
|
+
loop do
|
210
|
+
if @deliberate_close
|
211
|
+
sleep 5
|
212
|
+
next
|
213
|
+
end
|
214
|
+
_connect
|
215
|
+
sleep 5
|
214
216
|
end
|
215
|
-
else
|
216
|
-
@state = CONNECTION_STATE::ERROR
|
217
217
|
end
|
218
|
-
rescue Errno::ECONNREFUSED, Errno::ECONNRESET
|
219
|
-
@failed_reconnect_attempts += 1
|
220
|
-
on_error("Can't connect! Deepstream server unreachable on #{@url}")
|
221
|
-
info("Can't connect. Next attempt in #{reconnect_interval} seconds.")
|
222
|
-
sleep(reconnect_interval)
|
223
|
-
retry
|
224
|
-
rescue => e
|
225
|
-
on_exception(e)
|
226
218
|
end
|
227
219
|
|
228
|
-
def
|
229
|
-
|
220
|
+
def _connect(url = @url)
|
221
|
+
@log.info "Trying to connect to #{url}" if @verbose
|
222
|
+
endpoint = Async::HTTP::Endpoint.parse(url)
|
223
|
+
Async::WebSocket::Client.connect(endpoint) do |connection|
|
224
|
+
on_open
|
225
|
+
@task.async do
|
226
|
+
loop do
|
227
|
+
break if ( connection.closed? || @deliberate_close )
|
228
|
+
while !@message_buffer.empty? && (logged_in? || !@message_buffer[0].needs_authentication?)
|
229
|
+
msg = @message_buffer.shift
|
230
|
+
next if msg.expired?
|
231
|
+
encoded_msg = msg.to_s.encode(Encoding::UTF_8)
|
232
|
+
@log.info "Sending msg = #{msg.inspect}" if @verbose
|
233
|
+
connection.write(encoded_msg)
|
234
|
+
connection.flush rescue @message_buffer.unshift(msg)
|
235
|
+
end
|
236
|
+
@task.sleep 0.001
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
loop do
|
241
|
+
on_message(connection.read)
|
242
|
+
break if ( connection.closed? || @deliberate_close )
|
243
|
+
end
|
244
|
+
|
245
|
+
rescue => e
|
246
|
+
@log.error "Connection error #{e.message}"
|
247
|
+
on_exception(e)
|
248
|
+
ensure
|
249
|
+
connection.close
|
250
|
+
end
|
251
|
+
on_close
|
230
252
|
end
|
231
253
|
end
|
232
254
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require_relative './ack_timeout_registry'
|
2
|
+
require_relative './constants'
|
3
|
+
require_relative './exceptions'
|
4
|
+
require_relative './helpers'
|
5
5
|
|
6
6
|
module Deepstream
|
7
7
|
class EventHandler
|
@@ -14,7 +14,7 @@ module Deepstream
|
|
14
14
|
|
15
15
|
def on(event, &block)
|
16
16
|
unless @callbacks[event]
|
17
|
-
@client.send_message(TOPIC::EVENT, ACTION::SUBSCRIBE, event)
|
17
|
+
@client.send_message(TOPIC::EVENT, ACTION::SUBSCRIBE, event) if @client.state == CONNECTION_STATE::OPEN
|
18
18
|
@ack_timeout_registry.add(event, "No ACK message received in time for #{event}")
|
19
19
|
end
|
20
20
|
@callbacks[event] = block
|
@@ -75,7 +75,7 @@ module Deepstream
|
|
75
75
|
|
76
76
|
def fire_event_callback(message)
|
77
77
|
event, data = message.data
|
78
|
-
|
78
|
+
@callbacks[event].call(Helpers.to_type(data))
|
79
79
|
end
|
80
80
|
|
81
81
|
def fire_listen_callback(message)
|
data/lib/deepstream/helpers.rb
CHANGED
@@ -4,7 +4,7 @@ module Deepstream
|
|
4
4
|
module Helpers
|
5
5
|
SCHEME = 'ws://'
|
6
6
|
DEFAULT_PORT = 6020
|
7
|
-
DEFAULT_PATH = 'deepstream'
|
7
|
+
DEFAULT_PATH = 'deepstream-v3'
|
8
8
|
|
9
9
|
def self.to_deepstream_type(value)
|
10
10
|
case value
|
@@ -34,13 +34,9 @@ module Deepstream
|
|
34
34
|
def self.default_options
|
35
35
|
{
|
36
36
|
ack_timeout: nil,
|
37
|
-
autologin: true,
|
38
37
|
credentials: {},
|
39
38
|
heartbeat_interval: nil,
|
40
|
-
|
41
|
-
max_reconnect_interval: 30,
|
42
|
-
reconnect_interval: 1,
|
43
|
-
emit_timeout: 0,
|
39
|
+
in_thread: true,
|
44
40
|
verbose: false,
|
45
41
|
debug: false
|
46
42
|
}
|
@@ -48,9 +44,9 @@ module Deepstream
|
|
48
44
|
|
49
45
|
def self.url(url)
|
50
46
|
url.tap do |url|
|
51
|
-
url.prepend(SCHEME) unless url.start_with?(
|
47
|
+
url.prepend(SCHEME) unless url.start_with?(/ws(s|)\:\/\//)
|
52
48
|
url.concat(":#{DEFAULT_PORT}") unless url[/\:\d+/]
|
53
|
-
url.concat("/#{DEFAULT_PATH}") unless url[
|
49
|
+
url.concat("/#{DEFAULT_PATH}") unless url[/:\d+\/\S+$/]
|
54
50
|
end
|
55
51
|
end
|
56
52
|
|
data/lib/deepstream/list.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative './record'
|
2
2
|
|
3
3
|
module Deepstream
|
4
4
|
class List < Record
|
@@ -37,6 +37,12 @@ module Deepstream
|
|
37
37
|
@data.map { |record_name| @client.get(record_name) }
|
38
38
|
end
|
39
39
|
|
40
|
+
def end_reinitializing
|
41
|
+
reset_version
|
42
|
+
set
|
43
|
+
@is_reinitializing = false
|
44
|
+
end
|
45
|
+
|
40
46
|
private
|
41
47
|
|
42
48
|
def set
|
data/lib/deepstream/message.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'json'
|
2
|
-
|
2
|
+
require_relative './constants'
|
3
3
|
|
4
4
|
module Deepstream
|
5
5
|
class Message
|
@@ -9,18 +9,24 @@ module Deepstream
|
|
9
9
|
args.first.is_a?(self) ? args.first : new(*args)
|
10
10
|
end
|
11
11
|
|
12
|
-
def initialize(*args
|
12
|
+
def initialize(*args)
|
13
13
|
if args.one?
|
14
14
|
args = args.first.delete(MESSAGE_SEPARATOR).split(MESSAGE_PART_SEPARATOR)
|
15
15
|
end
|
16
|
-
@sending_deadline =
|
16
|
+
@sending_deadline = nil
|
17
17
|
@topic, @action = args.take(2).map(&:to_sym)
|
18
18
|
@data = args.drop(2)
|
19
|
+
rescue
|
20
|
+
''
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_timeout(timeout)
|
24
|
+
@sending_deadline = Time.now + timeout
|
19
25
|
end
|
20
26
|
|
21
27
|
def to_s
|
22
28
|
args = [@topic, @action]
|
23
|
-
args << @data unless @data.empty?
|
29
|
+
args << @data unless (@data.nil? || @data.empty?)
|
24
30
|
args.join(MESSAGE_PART_SEPARATOR).concat(MESSAGE_SEPARATOR)
|
25
31
|
end
|
26
32
|
|
data/lib/deepstream/record.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'json'
|
2
|
-
|
3
|
-
|
2
|
+
require_relative './constants'
|
3
|
+
require_relative './helpers'
|
4
4
|
|
5
5
|
module Deepstream
|
6
6
|
class Record
|
@@ -9,11 +9,29 @@ module Deepstream
|
|
9
9
|
@name = name
|
10
10
|
@data = {}
|
11
11
|
@version = nil
|
12
|
+
@is_reinitializing = false
|
13
|
+
@data_cache = {}
|
12
14
|
@client.send_message(TOPIC::RECORD, ACTION::CREATEORREAD, @name)
|
13
15
|
end
|
14
16
|
|
15
|
-
def
|
16
|
-
@
|
17
|
+
def reset_version
|
18
|
+
@version = 0
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_reinitializing?
|
22
|
+
@is_reinitializing
|
23
|
+
end
|
24
|
+
|
25
|
+
def start_reinitializing
|
26
|
+
@is_reinitializing = true
|
27
|
+
@data_cache = @data
|
28
|
+
@client.send_message(TOPIC::RECORD, ACTION::CREATEORREAD, @name, priority: true)
|
29
|
+
end
|
30
|
+
|
31
|
+
def end_reinitializing
|
32
|
+
reset_version
|
33
|
+
set(@data_cache)
|
34
|
+
@is_reinitializing = false
|
17
35
|
end
|
18
36
|
|
19
37
|
def inspect
|
@@ -1,7 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require_relative './constants'
|
2
|
+
require_relative './exceptions'
|
3
|
+
require_relative './list'
|
4
|
+
require_relative './record'
|
5
5
|
|
6
6
|
module Deepstream
|
7
7
|
class RecordHandler
|
@@ -10,6 +10,13 @@ module Deepstream
|
|
10
10
|
@records = {}
|
11
11
|
end
|
12
12
|
|
13
|
+
def reinitialize
|
14
|
+
@records.map do |record|
|
15
|
+
name, rec = record
|
16
|
+
rec.start_reinitializing
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
13
20
|
def on_message(message)
|
14
21
|
case message.action
|
15
22
|
when ACTION::ACK then nil
|
@@ -55,6 +62,7 @@ module Deepstream
|
|
55
62
|
|
56
63
|
def read(message)
|
57
64
|
name, *data = message.data
|
65
|
+
return @records[name].end_reinitializing if @records[name]&.is_reinitializing?
|
58
66
|
@records[name]&.read(*data)
|
59
67
|
end
|
60
68
|
|
metadata
CHANGED
@@ -1,29 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deepstream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Currency-One S.A.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: async
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.25.0
|
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
|
-
version:
|
26
|
+
version: 1.25.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: async-io
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.29.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.29.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: async-http
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.52.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.52.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: async-websocket
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.14.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.14.0
|
27
69
|
- !ruby/object:Gem::Dependency
|
28
70
|
name: cucumber
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,7 +138,7 @@ dependencies:
|
|
96
138
|
version: '0'
|
97
139
|
description: Basic ruby client for the deepstream.io server
|
98
140
|
email:
|
99
|
-
-
|
141
|
+
- ruby@currency-one.com
|
100
142
|
executables: []
|
101
143
|
extensions: []
|
102
144
|
extra_rdoc_files: []
|
@@ -110,6 +152,7 @@ files:
|
|
110
152
|
- deepstream.gemspec
|
111
153
|
- lib/deepstream.rb
|
112
154
|
- lib/deepstream/ack_timeout_registry.rb
|
155
|
+
- lib/deepstream/async_patch.rb
|
113
156
|
- lib/deepstream/client.rb
|
114
157
|
- lib/deepstream/constants.rb
|
115
158
|
- lib/deepstream/error_handler.rb
|
@@ -139,8 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
182
|
- !ruby/object:Gem::Version
|
140
183
|
version: '0'
|
141
184
|
requirements: []
|
142
|
-
|
143
|
-
rubygems_version: 2.6.8
|
185
|
+
rubygems_version: 3.0.3
|
144
186
|
signing_key:
|
145
187
|
specification_version: 4
|
146
188
|
summary: deepstream.io ruby client
|