ducts-client 0.1.2 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ffa6e977093a93d86411dfd32a683b6a693ca31f5c59f294be567cbbacca6902
4
- data.tar.gz: 13ed75278f6065bfb6256262aea24c0e5c23c581ab74ac10f8d1471c7cccb475
3
+ metadata.gz: e4ed02a6ed450d3495ea4d27af20b735e50959f1d95042dccf7afcca9331e079
4
+ data.tar.gz: f8a5f500b92af0ff4a6f3fca4f4590b480534976c412c969944919ecb7d5c261
5
5
  SHA512:
6
- metadata.gz: e93b5030eb9adbfd630558e355cb05ce9569a04e25eaca3b8be2554a75a62428ad8a98f7712c25575180ec4896e4b4ad0da3ea969e598ade52ee4c0cb2102727
7
- data.tar.gz: 7a322a50470f06e148f097e5102e0d45e527e07603441883e92ce7f919c6d3b3a0d47bb908f97778659bcf895bb552d5485bd1e388a89e2d069ea449ce363103
6
+ metadata.gz: e7621536c5e0dafabfa1d6f47eb0d69a6f96188251e2c83ddc33aeb1d58abc8a32d5ff1b88d7c39dad1c0040d063f428457e2fde85aca1be8c3d4af541ed06e9
7
+ data.tar.gz: 611bd6b7d8bf79eef1abff322f98723e9239a5f63a6f94443baf0a104263eb937d626d06ddaf8cda5884144deb72f4c50c005ff439ce0ce3bd69c64441c919fd
data/lib/ducts/client.rb CHANGED
@@ -56,6 +56,8 @@ module Ducts
56
56
  end
57
57
  end
58
58
 
59
+ DuctEventHandlerReturnValue = Struct.new(:value)
60
+
59
61
  class ConnectionEventListener < DuctEventListener
60
62
  attr_writer :onopen, :onclose, :onerror, :onmessage
61
63
  def onopen(event)
@@ -118,7 +120,9 @@ module Ducts
118
120
 
119
121
  @_last_rid = nil
120
122
  @_ws = nil
121
- @_waiting_completion = Hash.new
123
+ @_waiting_message_completion = Hash.new
124
+ @_waiting_closed_completion = Array.new
125
+ @_loop_queues = Hash.new
122
126
  end
123
127
 
124
128
  def next_rid
@@ -130,29 +134,13 @@ module Ducts
130
134
  next_id
131
135
  end
132
136
 
133
- def open(wsd_url, uuid = nil, **params)
134
- _open(wsd_url, uuid, **params)
135
- end
136
-
137
- def reconnect
138
- _reconnect
139
- end
140
-
141
- def send(rid, eid, data)
142
- _send(rid, eid, data)
143
- end
144
-
145
- def call(eid, data)
146
- _call(eid, data)
147
- end
148
-
149
- def close
150
- _close
151
- end
152
-
153
137
  def set_event_handler(event_id, &handler)
154
138
  @_event_handler ||= {}
155
- @_event_handler[event_id] = handler
139
+ if handler
140
+ @_event_handler.store(event_id, handler)
141
+ else
142
+ @_event_handler.delete(event_id)
143
+ end
156
144
  end
157
145
 
158
146
  def state
@@ -163,16 +151,16 @@ module Ducts
163
151
  end
164
152
  end
165
153
 
166
- private
167
- def _reconnect(wsd)
168
- if wsd
169
- @WSD = wsd
170
- @EVENT = @WSD['EVENT']
154
+ def reconnect
155
+ completion = EM::Completion.new
156
+ if @_ws
157
+ completion.succeed(self)
158
+ return completion;
171
159
  end
172
- return if @_ws
173
160
  Faye::WebSocket::Client.new(@WSD['websocket_url_reconnect']).tap do |ws|
174
161
  ws.on(:open) do |event|
175
162
  @_ws = ws
163
+ completion.succeed(self)
176
164
  connection_event = DuctConnectionEvent.new('onopen', event)
177
165
  _onreconnect(connection_event)
178
166
  @connection_listener.onopen(connection_event)
@@ -192,10 +180,15 @@ module Ducts
192
180
  @connection_listener.onerror(connection_event)
193
181
  end
194
182
  end
183
+ completion
195
184
  end
196
185
 
197
- def _open(wsd_url, uuid, **params)
198
- return if @_ws
186
+ def open(wsd_url, uuid = nil, **params)
187
+ completion = EM::Completion.new
188
+ if @_ws
189
+ completion.succeed(self)
190
+ return completion;
191
+ end
199
192
  begin
200
193
  query = '?uuid=' + (uuid || 'dummy') + params.map{ |k, v| "&#{k}=#{v}" }.join
201
194
  uri = URI.parse(wsd_url + query)
@@ -210,6 +203,7 @@ module Ducts
210
203
  Faye::WebSocket::Client.new(@WSD['websocket_url']).tap do |ws|
211
204
  ws.on(:open) do |event|
212
205
  @_ws = ws
206
+ completion.succeed(self)
213
207
  connection_event = DuctConnectionEvent.new('onopen', event)
214
208
  _onopen(connection_event)
215
209
  @connection_listener.onopen(connection_event)
@@ -225,6 +219,19 @@ module Ducts
225
219
  @connection_listener.onerror(connection_event)
226
220
  end
227
221
  ws.on(:close) do |event|
222
+ @_ws = nil
223
+ case event.code
224
+ when 1000
225
+ @_waiting_closed_completion.each do |waiting_closed_completion|
226
+ waiting_closed_completion.succeed(event)
227
+ end
228
+ else
229
+ p event.code
230
+ @_waiting_closed_completion.each do |waiting_closed_completion|
231
+ waiting_closed_completion.fail(event)
232
+ end
233
+ end
234
+ @_waiting_closed_completion.clear
228
235
  connection_event = DuctConnectionEvent.new('onclose', event)
229
236
  @connection_listener.onclose(connection_event)
230
237
  end
@@ -232,67 +239,69 @@ module Ducts
232
239
  rescue => error
233
240
  @connection_listener.onerror(DuctConnectionEvent.new('onerror', error))
234
241
  end
242
+ completion
243
+ end
244
+
245
+ def event_send(rid, eid, data)
246
+ msgpack = [ rid, eid, data ].to_msgpack
247
+ @_ws.send(msgpack.chars.map(&:ord))
248
+ rid
235
249
  end
236
250
 
251
+ def event_call(eid, data)
252
+ rid = next_rid
253
+ event_send(rid, eid, data)
254
+ warn Message.construct(Message::Level::WARNING, 'request ID is duplicated.') if @_waiting_message_completion.keys.include? rid
255
+ EM::Completion.new.tap { |completion| @_waiting_message_completion[rid] = completion }
256
+ end
257
+
258
+ def close
259
+ completion = EM::Completion.new
260
+ if @_ws
261
+ @_ws.close
262
+ @_waiting_closed_completion.push(completion)
263
+ else
264
+ completion.succeed(nil)
265
+ end
266
+ completion
267
+ end
268
+
269
+ private
237
270
  def _onopen(event)
238
271
  @_send_timestamp = Time.now.to_f
239
272
  @_time_offset = 0
240
273
  @_time_latency = 0
241
274
  @_time_count = 0
242
- set_event_handler(@EVENT['ALIVE_MONITORING']) do |rid, eid, data|
243
- client_received = Time.now.to_f
244
- server_sent, server_received = data
245
- client_sent = @_send_timestamp
246
- new_offset = ((server_received - client_sent) - (client_received - server_sent)) / 2
247
- new_latency = ((client_received - client_sent) - (server_sent - server_received)) / 2
248
- @_time_offset = (@_time_offset * @_time_count + new_offset) / (@_time_count + 1)
249
- @_time_latency = (@_time_latency * @_time_count + new_latency) / (@_time_count + 1)
250
- @_time_count += 1
251
- end
275
+ set_event_handler(@EVENT['ALIVE_MONITORING'], &method(:_alive_monitoring_handler))
276
+ set_event_handler(@EVENT['LOOP_RESPONSE_START'], &method(:_loop_response_handler))
277
+ set_event_handler(@EVENT['LOOP_RESPONSE_NEXT'], &method(:_loop_response_handler))
278
+ set_event_handler(@EVENT['LOOP_RESPONSE_END'], &method(:_loop_response_end_handler))
279
+ set_event_handler(@EVENT['DIVIDED_RESPONSE_APPEND'], &method(:_divided_response_append_handler))
280
+ set_event_handler(@EVENT['DIVIDED_RESPONSE_END'], &method(:_divided_response_end_handler))
252
281
  rid = next_rid
253
282
  eid = @EVENT['ALIVE_MONITORING']
254
283
  value = @_send_timestamp
255
- send(rid, eid, value)
284
+ event_send(rid, eid, value)
256
285
  end
257
286
 
258
287
  def _onreconnect(connection_event)
259
288
  end
260
289
 
261
- def _send(rid, eid, data)
262
- msgpack = [ rid, eid, data ].to_msgpack
263
- @_ws.send(msgpack.chars.map(&:ord))
264
- rid
265
- end
266
-
267
- def _call(eid, data)
268
- rid = next_rid
269
- _send(rid, eid, data)
270
- raise if @_waiting_completion.keys.include? rid
271
- EM::Completion.new.tap { |completion| @_waiting_completion[rid] = completion }
272
- end
273
-
274
- def _close
275
- begin
276
- @_ws.close if @_ws
277
- ensure
278
- @_ws = nil
279
- end
280
- end
281
-
282
290
  def _onmessage(connection_event)
283
291
  begin
284
292
  rid, eid, data = %i(rid eid data).map{ |name| connection_event.source.public_send(name) }
285
293
  begin
286
294
  @catchall_event_handler.call(rid, eid, data)
287
295
  handle = @_event_handler[eid]
288
- handle = @uncaught_event_handler unless handle
289
- handle.call(rid, eid, data)
290
- completion = @_waiting_completion.delete(rid)
296
+ handle ||= @uncaught_event_handler
297
+ ret = handle.call(rid, eid, data)
298
+ handled_data = (ret.instance_of? DuctEventHandlerReturnValue)? ret.value : data
299
+ completion = @_waiting_message_completion.delete(rid)
291
300
  if completion
292
301
  if eid > 0
293
- completion.succeed(data)
302
+ completion.succeed(handled_data)
294
303
  else
295
- completion.fail(DuctError.execption(data))
304
+ completion.fail(DuctError.exception(handled_data))
296
305
  end
297
306
  end
298
307
  rescue => error
@@ -302,5 +311,55 @@ module Ducts
302
311
  @event_error_handler.call(-1, -1, nil, error)
303
312
  end
304
313
  end
314
+
315
+ def _alive_monitoring_handler(rid, eid, data)
316
+ client_received = Time.now.to_f
317
+ server_sent, server_received = data
318
+ client_sent = @_send_timestamp
319
+ new_offset = ((server_received - client_sent) - (client_received - server_sent)) / 2
320
+ new_latency = ((client_received - client_sent) - (server_sent - server_received)) / 2
321
+ @_time_offset = (@_time_offset * @_time_count + new_offset) / (@_time_count + 1)
322
+ @_time_latency = (@_time_latency * @_time_count + new_latency) / (@_time_count + 1)
323
+ @_time_count += 1
324
+ end
325
+
326
+ def _loop_response_handler(rid, eid, data)
327
+ warn Message.construct(Message::Level::WARNING, 'loop response has error.') if eid.negative?
328
+ source_eid = data[1]
329
+ source_data = data[2]
330
+ @catchall_event_handler.call(rid, source_eid, source_data)
331
+ handle = @_event_handler[source_eid.abs]
332
+ handle ||= @uncaught_event_handler
333
+ ret = handle.call(rid, source_eid, source_data)
334
+ handled_source_data = (ret.instance_of? DuctEventHandlerReturnValue)? ret.value : source_data
335
+ @_loop_queues[rid] ||= EM::Queue.new
336
+ queue = @_loop_queues[rid]
337
+ queue.push(handled_source_data) if handled_source_data
338
+ DuctEventHandlerReturnValue.new(queue)
339
+ end
340
+
341
+ def _loop_response_end_handler(rid, eid, data)
342
+ warn Message.construct(Message::Level::WARNING, 'loop response end has error.') if eid.negative?
343
+ source_eid = data[1]
344
+ source_data = data[2]
345
+ warn Message.construct(Message::Level::WARNING, "loop response end has data: #{source_data}.") if source_data
346
+ @catchall_event_handler.call(rid, source_eid, source_data)
347
+ handle = @_event_handler[source_eid.abs]
348
+ handle ||= @uncaught_event_handler
349
+ handle.call(rid, source_eid, source_data)
350
+ queue = @_loop_queues.delete(rid)
351
+ queue.push(nil)
352
+ DuctEventHandlerReturnValue.new(source_eid)
353
+ end
354
+
355
+ def _divided_response_append_handler(rid, eid, data)
356
+ raise 'Not implemented.'
357
+ # TODO
358
+ end
359
+
360
+ def _divided_response_end_handler(rid, eid, data)
361
+ raise 'Not implemented.'
362
+ # TODO
363
+ end
305
364
  end
306
365
  end
@@ -4,8 +4,8 @@ module Ducts
4
4
  class Client
5
5
  module Version
6
6
  MAJOR = 0
7
- MINOR = 1
8
- PATCH = 2
7
+ MINOR = 4
8
+ PATCH = 4
9
9
  end
10
10
 
11
11
  VERSION = [ Version::MAJOR, Version::MINOR, Version::PATCH ].map(&:to_s).join('.')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ducts-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenshiro Ueda
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-19 00:00:00.000000000 Z
11
+ date: 2021-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faye-websocket