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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 6a195b77c67902febe4748081ede0bf486630065
4
- data.tar.gz: 8663b916c19058e8f74b14d329bf391f5b33bfc1
2
+ SHA256:
3
+ metadata.gz: a8cafac8651bd0cb90746e47c290919eb51acb2058e24fd345759ffa0a459996
4
+ data.tar.gz: 29d4d74d4e417afd703e0ad190b138b7145cf8699cd5bb1c90ca0d006b95b83a
5
5
  SHA512:
6
- metadata.gz: 6a7a86d7cdca2170457a2ce25e73f71d2380106728a69ab0840521dc8900b30820afe2032e6341291f38342953f26c7a3ef9b6076d123fed68c0e95e9711faab
7
- data.tar.gz: 8c30325353d28fac3dbf8f7ab4d4cc361d454f6628f0758efd5796f7bb20b5a0ad693b084c4f5c9168c1221263652fb496e2b5879115f31d71fb520ac491a2c2
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
  [![Gem Version](https://badge.fury.io/rb/deepstream.svg)](http://badge.fury.io/rb/deepstream)
6
7
  [![Gem License](https://img.shields.io/badge/license-Apache-blue.svg)](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
- ### Development
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)
@@ -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.1"
7
+ spec.version = "1.0.3"
8
8
  spec.authors = ["Currency-One S.A."]
9
- spec.email = ["piotr.szczudlak@currency-one.com"]
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 'celluloid-websocket-client', '~> 0'
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'
@@ -11,4 +11,4 @@
11
11
  # See the License for the specific language governing permissions and
12
12
  # limitations under the License.
13
13
 
14
- require 'deepstream/client'
14
+ require_relative './deepstream/client'
@@ -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] = Celluloid.after(timeout) { @client.on_error(message) }
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.delete(name)&.cancel
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
@@ -1,23 +1,24 @@
1
1
  require 'forwardable'
2
- require 'celluloid/websocket/client'
3
- require 'deepstream/constants'
4
- require 'deepstream/error_handler'
5
- require 'deepstream/event_handler'
6
- require 'deepstream/record_handler'
7
- require 'deepstream/helpers'
8
- require 'deepstream/message'
9
- require 'deepstream/exceptions'
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, @login_requested, @deliberate_close = false
34
- @failed_reconnect_attempts = 0
34
+ @challenge_denied, @@deliberate_close = false
35
35
  @state = CONNECTION_STATE::CLOSED
36
- Celluloid.logger.level = @options[:verbose] ? LOG_LEVEL::INFO : LOG_LEVEL::OFF
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("Websocket connection opened")
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("Incoming message: #{message.inspect}")
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
- @login_requested = false
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
- @connection.close
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
- return unable_to_send_message(message) if !logged_in? && message.needs_authentication?
117
- info("Sending message: #{message.inspect}")
118
- @connection.text(message.to_s)
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
- info("Placing a message #{message.inspect} in the buffer, waiting for authentication")
131
- @message_buffer << message
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
- login if @options[:autologin] || @login_requested
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
- close
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
- close
191
- connect(message.data.last)
194
+ on_close
195
+ @url = message.data.last
192
196
  end
193
197
 
194
- def connect(url = @url, reraise = false, force = false)
195
- return if @connection_requested && !force
196
- info("Trying to connect to #{url}.")
197
- @connection_requested = true
198
- @connection = Celluloid::WebSocket::Client.new(url, Actor.current)
199
- rescue => e
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 reconnect
205
- info("Trying to reconnect to #{@url}")
206
- if @options[:max_reconnect_attempts].nil? || @failed_reconnect_attempts < @options[:max_reconnect_attempts]
207
- @state = CONNECTION_STATE::RECONNECTING
208
- @login_requested = true
209
- connect(@url, true, true)
210
- sleep(5)
211
- if !logged_in?
212
- close
213
- reconnect
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 reconnect_interval
229
- [@options[:reconnect_interval] * @failed_reconnect_attempts, @options[:max_reconnect_interval]].min
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,6 +1,6 @@
1
- require 'deepstream/constants'
2
- require 'deepstream/helpers'
3
- require 'deepstream/message'
1
+ require_relative './constants'
2
+ require_relative './helpers'
3
+ require_relative './message'
4
4
 
5
5
  module Deepstream
6
6
  class ErrorHandler
@@ -1,7 +1,7 @@
1
- require 'deepstream/ack_timeout_registry'
2
- require 'deepstream/constants'
3
- require 'deepstream/exceptions'
4
- require 'deepstream/helpers'
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
- Celluloid::Future.new { @callbacks[event].call(Helpers.to_type(data)) }
78
+ @callbacks[event].call(Helpers.to_type(data))
79
79
  end
80
80
 
81
81
  def fire_listen_callback(message)
@@ -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
- max_reconnect_attempts: nil,
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?(SCHEME)
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[/\/\w+$/]
49
+ url.concat("/#{DEFAULT_PATH}") unless url[/:\d+\/\S+$/]
54
50
  end
55
51
  end
56
52
 
@@ -1,4 +1,4 @@
1
- require 'deepstream/record'
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
@@ -1,5 +1,5 @@
1
1
  require 'json'
2
- require 'deepstream/constants'
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, timeout: nil)
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 = Time.now + timeout if timeout
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
 
@@ -1,6 +1,6 @@
1
1
  require 'json'
2
- require 'deepstream/constants'
3
- require 'deepstream/helpers'
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 get_name
16
- @name
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
- require 'deepstream/constants'
2
- require 'deepstream/exceptions'
3
- require 'deepstream/list'
4
- require 'deepstream/record'
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.1
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: 2017-03-20 00:00:00.000000000 Z
11
+ date: 2021-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: celluloid-websocket-client
14
+ name: async
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
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: '0'
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
- - piotr.szczudlak@currency-one.com
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
- rubyforge_project:
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