hakuban 0.6.1 → 0.6.2

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: 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