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 +4 -4
- data/lib/hakuban/event-queue.rb +77 -0
- data/lib/hakuban/hakuban.rb +49 -39
- data/lib/hakuban/manager.rb +56 -40
- data/lib/hakuban/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d0b0d54e3b6dce8ecd11b991e94768247f2e978cca397d430fcab6bfd987484
|
4
|
+
data.tar.gz: 81466178ba54513cb665cd49800599125bda1ba108f7eee71efff3e5b496cbb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/hakuban/hakuban.rb
CHANGED
@@ -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
|
240
|
+
def new_callback_event_queue
|
269
241
|
raise "Attempt to use after 'drop'" if not @object_observe_pointer
|
270
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
407
|
+
def new_callback_event_queue
|
417
408
|
raise "Attempt to use after 'drop'" if not @tag_observe_pointer
|
418
|
-
|
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
|
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
|
-
|
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?
|
data/lib/hakuban/manager.rb
CHANGED
@@ -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.
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
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
|
-
|
73
|
-
def
|
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)
|
data/lib/hakuban/version.rb
CHANGED
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.
|
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-
|
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
|