hakuban 0.6.1 → 0.6.2

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
2
  SHA256:
3
- metadata.gz: f12beca62a4975af1ee3f85d5ec83e85753a6f6bb95fb36529c284d88eba41c5
4
- data.tar.gz: ca7a3c890c4ba1b7dc337ac1e3120b8d5d260c8170f641493067b5f75060c3ab
3
+ metadata.gz: 6d0b0d54e3b6dce8ecd11b991e94768247f2e978cca397d430fcab6bfd987484
4
+ data.tar.gz: 81466178ba54513cb665cd49800599125bda1ba108f7eee71efff3e5b496cbb5
5
5
  SHA512:
6
- metadata.gz: fb3e86f190c140edb9658f42f33cb9bfdad718cb6b04a9f1bced7240ed2b64716d43ab651f3551b4ee084d103fdfc3bf038dc7e3f91332f1bac692e5b9b7001f
7
- data.tar.gz: fd40ec84a8e7f713f857768e84dd0f5554beb00adf586adf7e739e12e1920cb568387df5cc8c4085c7bec83fbffc36a5d16bbe7211481774e849b5dda402fab6
6
+ metadata.gz: dc7157372663dc871a85b36ee042e0fc12b66ad45fb322398b593086b47896167ab4cb913ab8b1f636071a9a006d2a3ab3af34b6d32e4024d7f3121dc4d9e19c
7
+ data.tar.gz: 6b0b7c59f66be811b16322574f8f0670c5802760b8cf8e690b3d4fa4107ea17dffa1e085c0c9607a72fa0a025eef0665087d5b18b0d671e43bab1cf7b5eea95f
@@ -0,0 +1,77 @@
1
+ #TODO: rebuild to handle event squashing on rust side
2
+
3
+ require 'ostruct'
4
+
5
+ require_relative './ffi.rb'
6
+
7
+
8
+ module Hakuban
9
+
10
+ class Event < OpenStruct; end
11
+
12
+ class ObjectDescriptorCallbackEventQueue
13
+
14
+ def initialize(pointer)
15
+ @events_pointer = ::FFI::AutoPointer.new(pointer, proc { |ptr| FFI.hakuban_object_descriptor_events_return(ptr) })
16
+ end
17
+
18
+
19
+ # WARNING: this callback may be run from a separate, non-ruby, thread
20
+ def callback_register(&callback)
21
+ ffi_callback = proc { |_userdata, ffi_descriptor, ffi_action|
22
+ action = Hakuban::action_int_to_symbol(ffi_action)
23
+ descriptor = ObjectDescriptor.from_ffi(ffi_descriptor)
24
+ callback.call(descriptor, action)
25
+ }
26
+ @callback_pointer = ::FFI::AutoPointer.new(
27
+ FFI::hakuban_object_descriptor_events_callback_register(@events_pointer, ffi_callback, ::FFI::Pointer::NULL),
28
+ proc { |ptr| FFI::hakuban_object_descriptor_events_callback_unregister(ptr) }
29
+ )
30
+ end
31
+
32
+
33
+ def callback_unregister
34
+ @callback_pointer.free
35
+ @callback_pointer = nil
36
+ end
37
+
38
+
39
+ def drop
40
+ @events_pointer.free
41
+ @events_pointer = nil
42
+ end
43
+
44
+ end
45
+
46
+
47
+ class ObjectDescriptorEventQueue
48
+
49
+ def initialize(contract)
50
+ @contract = contract
51
+ @queue = Queue.new
52
+ @ffi_callback = proc { |descriptor, action|
53
+ @queue << Hakuban::Event.new(action: action, descriptor: descriptor)
54
+ }
55
+ @ffi_events = @contract.new_callback_event_queue
56
+ @ffi_events.callback_register(&@ffi_callback)
57
+ end
58
+
59
+
60
+ #def push(event)
61
+ # @queue << event
62
+ #end
63
+
64
+
65
+ def next_event; next_change; end
66
+ def next_change
67
+ @queue.pop
68
+ end
69
+
70
+
71
+ def close
72
+ @queue.close
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -2,6 +2,7 @@ require 'set'
2
2
  require 'ostruct'
3
3
 
4
4
  require_relative './ffi.rb'
5
+ require_relative './event-queue.rb'
5
6
 
6
7
  #TODO: explicit drops?
7
8
  #TODO: privative methods
@@ -215,36 +216,6 @@ module Hakuban
215
216
  end
216
217
 
217
218
 
218
- class ObjectDescriptorEvents
219
- def initialize(pointer)
220
- @events_pointer = ::FFI::AutoPointer.new(pointer, proc { |ptr| FFI.hakuban_object_descriptor_events_return(ptr) })
221
- end
222
-
223
- # WARNING: this callback may be run from a separate, non-ruby, thread
224
- def callback_register(&callback)
225
- ffi_callback = proc { |_userdata, ffi_descriptor, ffi_action|
226
- action = Hakuban::action_int_to_symbol(ffi_action)
227
- descriptor = ObjectDescriptor.from_ffi(ffi_descriptor)
228
- callback.call(descriptor, action)
229
- }
230
- @callback_pointer = ::FFI::AutoPointer.new(
231
- FFI::hakuban_object_descriptor_events_callback_register(@events_pointer, ffi_callback, ::FFI::Pointer::NULL),
232
- proc { |ptr| FFI::hakuban_object_descriptor_events_callback_unregister(ptr) }
233
- )
234
- end
235
-
236
- def callback_unregister
237
- @callback_pointer.free
238
- @callback_pointer = nil
239
- end
240
-
241
- def drop
242
- @events_pointer.free
243
- @events_pointer = nil
244
- end
245
-
246
- end
247
-
248
219
  class ObjectObserve
249
220
 
250
221
  attr_reader :descriptor
@@ -253,6 +224,7 @@ module Hakuban
253
224
  @local_node, @descriptor, @deserializer = local_node, descriptor, deserializer
254
225
  result = FFI::hakuban_object_observe_new(@local_node.local_node_pointer, descriptor.to_ffi)
255
226
  Hakuban::raise_if_error(result)
227
+ @queues = []
256
228
  @object_observe_pointer = ::FFI::AutoPointer.new(result[:object_observe_pointer], proc { |ptr| FFI::hakuban_object_observe_drop(ptr) })
257
229
  end
258
230
 
@@ -265,9 +237,16 @@ module Hakuban
265
237
  end
266
238
  end
267
239
 
268
- def events
240
+ def new_callback_event_queue
269
241
  raise "Attempt to use after 'drop'" if not @object_observe_pointer
270
- ObjectDescriptorEvents.new(FFI::hakuban_object_observe_events_get(@object_observe_pointer))
242
+ ObjectDescriptorCallbackEventQueue.new(FFI::hakuban_object_observe_events_get(@object_observe_pointer))
243
+ end
244
+
245
+ def new_event_queue
246
+ raise "Attempt to use after 'drop'" if not @object_observe_pointer
247
+ queue = ObjectDescriptorEventQueue.new(self)
248
+ @queues << queue
249
+ queue
271
250
  end
272
251
 
273
252
  def inspect
@@ -277,6 +256,8 @@ module Hakuban
277
256
  def drop
278
257
  @object_observe_pointer.free
279
258
  @object_observe_pointer = nil
259
+ @queues.each(&:close) #is this atomic?
260
+ @queues.clear
280
261
  end
281
262
 
282
263
  def dropped?
@@ -294,6 +275,7 @@ module Hakuban
294
275
  @local_node, @descriptor, @serializer = local_node, descriptor, serializer
295
276
  result = FFI::hakuban_object_expose_new(@local_node.local_node_pointer, descriptor.to_ffi)
296
277
  Hakuban::raise_if_error(result)
278
+ @queues = []
297
279
  @object_expose_pointer = ::FFI::AutoPointer.new(result[:object_expose_pointer], FFI::method(:hakuban_object_expose_drop))
298
280
  end
299
281
 
@@ -319,9 +301,16 @@ module Hakuban
319
301
  FFI::hakuban_object_expose_desynchronize(@object_expose_pointer, assignment)
320
302
  end
321
303
 
322
- def events
304
+ def new_callback_event_queue
305
+ raise "Attempt to use after 'drop'" if not @object_expose_pointer
306
+ ObjectDescriptorCallbackEventQueue.new(FFI::hakuban_object_expose_events_get(@object_expose_pointer))
307
+ end
308
+
309
+ def new_event_queue
323
310
  raise "Attempt to use after 'drop'" if not @object_expose_pointer
324
- ObjectDescriptorEvents.new(FFI::hakuban_object_expose_events_get(@object_expose_pointer))
311
+ queue = ObjectDescriptorEventQueue.new(self)
312
+ @queues << queue
313
+ queue
325
314
  end
326
315
 
327
316
  def inspect
@@ -331,7 +320,8 @@ module Hakuban
331
320
  def drop
332
321
  @object_expose_pointer.free
333
322
  @object_expose_pointer = nil
334
- end
323
+ @queues.each(&:close) #is this atomic?
324
+ @queues.clear end
335
325
 
336
326
  def dropped?
337
327
  @object_expose_pointer.nil?
@@ -394,6 +384,7 @@ module Hakuban
394
384
  @local_node, @descriptor, @deserializer = local_node, descriptor, deserializer
395
385
  result = FFI::hakuban_tag_observe_new(@local_node.local_node_pointer, @descriptor.to_ffi)
396
386
  Hakuban::raise_if_error(result)
387
+ @queues = []
397
388
  @tag_observe_pointer = ::FFI::AutoPointer.new(result[:tag_observe_pointer], FFI::method(:hakuban_tag_observe_drop))
398
389
  end
399
390
 
@@ -413,14 +404,23 @@ module Hakuban
413
404
  ObjectObserveState.new(result[:state], @deserializer)
414
405
  end
415
406
 
416
- def events
407
+ def new_callback_event_queue
417
408
  raise "Attempt to use after 'drop'" if not @tag_observe_pointer
418
- ObjectDescriptorEvents.new(FFI::hakuban_tag_observe_events_get(@tag_observe_pointer))
409
+ ObjectDescriptorCallbackEventQueue.new(FFI::hakuban_tag_observe_events_get(@tag_observe_pointer))
410
+ end
411
+
412
+ def new_event_queue
413
+ raise "Attempt to use after 'drop'" if not @tag_observe_pointer
414
+ queue = ObjectDescriptorEventQueue.new(self)
415
+ @queues << queue
416
+ queue
419
417
  end
420
418
 
421
419
  def drop
422
420
  @tag_observe_pointer.free
423
421
  @tag_observe_pointer = nil
422
+ @queues.each(&:close) #is this atomic?
423
+ @queues.clear
424
424
  end
425
425
 
426
426
  def dropped?
@@ -438,6 +438,7 @@ module Hakuban
438
438
  @local_node, @descriptor, @serializer = local_node, descriptor, serializer
439
439
  result = FFI::hakuban_tag_expose_new(@local_node.local_node_pointer, descriptor.to_ffi)
440
440
  Hakuban::raise_if_error(result)
441
+ @queues = []
441
442
  @tag_expose_pointer = ::FFI::AutoPointer.new(result[:tag_expose_pointer], FFI::method(:hakuban_tag_expose_drop))
442
443
  end
443
444
 
@@ -472,14 +473,23 @@ module Hakuban
472
473
  FFI::hakuban_tag_expose_object_desynchronize(@tag_expose_pointer, object_descriptor.to_ffi, assignment)
473
474
  end
474
475
 
475
- def events
476
+ def new_callback_event_queue
477
+ raise "Attempt to use after 'drop'" if not @tag_expose_pointer
478
+ ObjectDescriptorCallbackEventQueue.new(FFI::hakuban_tag_expose_events_get(@tag_expose_pointer))
479
+ end
480
+
481
+ def new_event_queue
476
482
  raise "Attempt to use after 'drop'" if not @tag_expose_pointer
477
- ObjectDescriptorEvents.new(FFI::hakuban_tag_expose_events_get(@tag_expose_pointer))
483
+ queue = ObjectDescriptorEventQueue.new(self)
484
+ @queues << queue
485
+ queue
478
486
  end
479
487
 
480
488
  def drop
481
489
  @tag_expose_pointer.free
482
490
  @tag_expose_pointer = nil
491
+ @queues.each(&:close) #is this atomic?
492
+ @queues.clear
483
493
  end
484
494
 
485
495
  def dropped?
@@ -14,6 +14,7 @@ module Hakuban
14
14
 
15
15
  def initialize(contract, object_class, block)
16
16
  @contract = contract
17
+ @objects_mutex = Mutex.new
17
18
  @objects = {}
18
19
  @running_handlers = {}
19
20
  @event_queue = Queue.new
@@ -23,60 +24,75 @@ module Hakuban
23
24
  @ffi_callback = proc { |descriptor, action|
24
25
  @event_queue << Event.new(action: action, descriptor: descriptor)
25
26
  }
26
- @ffi_events = @contract.events
27
+ @ffi_events = @contract.new_callback_event_queue
27
28
  @ffi_events.callback_register(&@ffi_callback)
28
29
 
29
30
  @async = async_run {
30
- while event = @event_queue.shift
31
- case event.action
32
- when :insert
33
- raise if @objects[event.descriptor]
34
- @objects[event.descriptor] = object_class.new(@contract, event.descriptor)
35
- @event_queue << Event.new(action: :handler_start, descriptor: event.descriptor) if block
36
- when :change
37
- raise if not @objects[event.descriptor]
38
- @objects[event.descriptor].do_change(:change)
39
- when :remove
40
- raise if not @objects[event.descriptor]
41
- @objects[event.descriptor].do_change(:remove)
42
- @objects.delete(event.descriptor)
43
- when :handler_start
44
- if (object = @objects[event.descriptor]) and !object.handler_already_run and !@running_handlers[event.descriptor]
45
- descriptor_for_lambda = event.descriptor
46
- @running_handlers[event.descriptor] = async_run {
47
- object.run(block)
48
- @event_queue << Event.new(action: :handler_finished, descriptor: descriptor_for_lambda) if @event_queue
49
- }
31
+ while @event_queue and event = @event_queue.shift
32
+ @objects_mutex.synchronize {
33
+ case event.action
34
+ when :insert
35
+ raise if @objects[event.descriptor]
36
+ @objects[event.descriptor] = object_class.new(@contract, event.descriptor)
37
+ @event_queue << Event.new(action: :handler_start, descriptor: event.descriptor) if block
38
+ when :change
39
+ raise if not @objects[event.descriptor]
40
+ @objects[event.descriptor].do_change(:change)
41
+ when :remove
42
+ raise if not @objects[event.descriptor]
43
+ @objects[event.descriptor].do_change(:remove)
44
+ @objects.delete(event.descriptor)
45
+ when :handler_start
46
+ if (object = @objects[event.descriptor]) and !object.handler_already_run and !@running_handlers[event.descriptor]
47
+ descriptor_for_lambda = event.descriptor
48
+ @running_handlers[event.descriptor] = async_run {
49
+ object.run(block)
50
+ @event_queue << Event.new(action: :handler_finished, descriptor: descriptor_for_lambda) if @event_queue
51
+ }
52
+ end
53
+ when :handler_finished
54
+ raise if not @running_handlers[event.descriptor]
55
+ @running_handlers.delete(event.descriptor)
56
+ @event_queue << Event.new(action: :handler_start, descriptor: event.descriptor) if @objects[event.descriptor]
57
+ when :drop
58
+ @ffi_events.callback_unregister
59
+ @objects.values.each { |object| object.do_change(:remove) }
60
+ while @running_handlers.size > 0
61
+ event = @event_queue.shift
62
+ @running_handlers.delete(event.descriptor) if event.action == :handler_finished
63
+ end
64
+ @event_queue.clear
65
+ @objects.clear
66
+ @contract.drop
67
+ @contract, @event_queue = nil, nil
68
+ break
50
69
  end
51
- when :handler_finished
52
- raise if not @running_handlers[event.descriptor]
53
- @running_handlers.delete(event.descriptor)
54
- @event_queue << Event.new(action: :handler_start, descriptor: event.descriptor) if @objects[event.descriptor]
55
- when :drop
56
- @ffi_events.callback_unregister
57
- @objects.values.each { |object| object.do_change(:remove) }
58
- while @running_handlers.size > 0
59
- event = @event_queue.shift
60
- @running_handlers.delete(event.descriptor) if event.action == :handler_finished
61
- end
62
- @event_queue.clear
63
- @objects.clear
64
- @contract.drop
65
- @contract, @event_queue = nil, nil
66
- break
67
- end
70
+ }
68
71
  end
69
72
  }
70
73
  end
71
74
 
72
- def objects; @objects; end
73
- def object; @objects.values.first; end
75
+
76
+ def objects
77
+ @objects_mutex.synchronize {
78
+ @objects.dup
79
+ }
80
+ end
81
+
82
+
83
+ def object
84
+ @objects_mutex.synchronize {
85
+ @objects.values.first
86
+ }
87
+ end
88
+
74
89
 
75
90
  def drop
76
91
  drop_nonblock
77
92
  async_join(@async)
78
93
  end
79
94
 
95
+
80
96
  def drop_nonblock
81
97
  if @contract
82
98
  @event_queue << Event.new(action: :drop)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hakuban
4
- VERSION = "0.6.1"
4
+ VERSION = "0.6.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hakuban
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - yunta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-06 00:00:00.000000000 Z
11
+ date: 2022-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -83,6 +83,7 @@ files:
83
83
  - lib/hakuban.rb
84
84
  - lib/hakuban/async.rb
85
85
  - lib/hakuban/engine.rb
86
+ - lib/hakuban/event-queue.rb
86
87
  - lib/hakuban/ffi.rb
87
88
  - lib/hakuban/hakuban.rb
88
89
  - lib/hakuban/manager.rb