hakuban 0.5.2 → 0.5.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 +4 -4
- data/examples/all-top-managed.rb +10 -15
- data/examples/all-top-simple.rb +3 -3
- data/lib/hakuban/hakuban.rb +86 -43
- data/lib/hakuban/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b1dd3c0a54ced0edb0c409842cb7d74ca6cadf8472ad6b7e15fec97198ef8ad
|
4
|
+
data.tar.gz: 228080f7a28f5718620a30af69cb4c277682508623937684fb961e0994b50a91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8afdbc65c6eee3ff1d4475f89b12b88f72c970eb37890aff2e66fcbba2ccac5b5cc897859aa8eedb727f6b484d999875f83176cc34698788d64f72bd96b4e577
|
7
|
+
data.tar.gz: c67bbfc8d9e3205973f33d5041fb71c642a41667156feadea39fed0bda72f1a0734912be440ee8b5cb4a6c83dff6d28da3ae36ee34ed76caee791ff80e3ffff8
|
data/examples/all-top-managed.rb
CHANGED
@@ -2,15 +2,10 @@ require 'hakuban'
|
|
2
2
|
require_relative './cpu-usage.rb'
|
3
3
|
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
attr_reader :id
|
10
|
-
|
11
|
-
def initialize(contract, descriptor)
|
12
|
-
super
|
13
|
-
@id = descriptor.json["id"]
|
5
|
+
|
6
|
+
class UtilizationManager < Hakuban::ObjectManager
|
7
|
+
def object_insert(object)
|
8
|
+
object.id = object.descriptor.json["id"]
|
14
9
|
end
|
15
10
|
end
|
16
11
|
|
@@ -18,17 +13,17 @@ end
|
|
18
13
|
id = "#{$$}@#{`hostname`.strip}"
|
19
14
|
|
20
15
|
hakuban = Hakuban::LocalNode.new
|
21
|
-
connector = Hakuban::WebsocketConnector.new("ws://localhost:3001")
|
22
|
-
all_utilizations = hakuban.tag("utilizations").observe.manage(
|
23
|
-
my_utilization = hakuban.object(["utilizations"],{id: id}).expose.manage(
|
16
|
+
connector = Hakuban::WebsocketConnector.new(hakuban, "ws://localhost:3001")
|
17
|
+
all_utilizations = hakuban.tag("utilizations").observe.manage(UtilizationManager.new)
|
18
|
+
my_utilization = hakuban.object(["utilizations"],{id: id}).expose.manage(UtilizationManager.new)
|
24
19
|
|
25
20
|
previous_cpu_usage_state = nil
|
26
21
|
loop {
|
27
22
|
previous_cpu_usage_state, cpu_usage = CPU::current_usage(previous_cpu_usage_state)
|
28
|
-
my_utilization.data =
|
23
|
+
my_utilization.data = {"percentage"=>cpu_usage} if cpu_usage
|
29
24
|
|
30
|
-
utilizations = all_utilizations.
|
31
|
-
[utilization.id, utilization.data&.
|
25
|
+
utilizations = all_utilizations.values.sort_by(&:id).map { |utilization|
|
26
|
+
[utilization.id, utilization.data&.dig("percentage")]
|
32
27
|
}.select { |id, utilization| utilization }
|
33
28
|
next sleep 1 if utilizations.empty?
|
34
29
|
|
data/examples/all-top-simple.rb
CHANGED
@@ -5,7 +5,7 @@ require_relative './cpu-usage.rb'
|
|
5
5
|
id = "#{$$}@#{`hostname`.strip}"
|
6
6
|
|
7
7
|
hakuban = Hakuban::LocalNode.new
|
8
|
-
connector = Hakuban::WebsocketConnector.new("ws://localhost:3001")
|
8
|
+
connector = Hakuban::WebsocketConnector.new(hakuban, "ws://localhost:3001")
|
9
9
|
all_utilizations = hakuban.tag("utilizations").observe
|
10
10
|
my_utilization = hakuban.object(["utilizations"],{id: id}).expose
|
11
11
|
|
@@ -13,11 +13,11 @@ previous_cpu_usage_state = nil
|
|
13
13
|
|
14
14
|
loop {
|
15
15
|
previous_cpu_usage_state, cpu_usage = CPU::current_usage(previous_cpu_usage_state)
|
16
|
-
my_utilization.set_object_state([Time.new.to_f],
|
16
|
+
my_utilization.set_object_state([Time.new.to_f],{ "percentage"=>cpu_usage }) if cpu_usage
|
17
17
|
|
18
18
|
all_utilizations.object_descriptors.map { |descriptor|
|
19
19
|
if data = all_utilizations.object_state(descriptor).data
|
20
|
-
puts "#{descriptor.json["id"]} -> #{data
|
20
|
+
puts "#{descriptor.json["id"]} -> #{data["percentage"]}"
|
21
21
|
end
|
22
22
|
}
|
23
23
|
|
data/lib/hakuban/hakuban.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'set'
|
2
|
+
require 'ostruct'
|
2
3
|
|
3
4
|
require_relative './ffi.rb'
|
4
5
|
|
@@ -50,20 +51,53 @@ module Hakuban
|
|
50
51
|
attr_reader :local_node_pointer #todo: hide
|
51
52
|
|
52
53
|
def initialize(name=nil)
|
54
|
+
@default_serializer = lambda { |data_type, data|
|
55
|
+
[["JSON"]+data_type, JSON.dump(data)]
|
56
|
+
}
|
57
|
+
@default_deserializer = lambda { |data_type, data|
|
58
|
+
raise "Expected JSON serialized data, got: #{dat_type}" if data_type[0] != "JSON"
|
59
|
+
[data_type[1..-1], JSON.load(data)]
|
60
|
+
}
|
53
61
|
Hakuban::logger_initialize("hakuban=warn", true)
|
54
62
|
result = FFI::hakuban_local_node_new(name || File.basename(caller_locations(0..1)[1].path))
|
55
63
|
Hakuban::raise_if_error(result)
|
56
64
|
@local_node_pointer = ::FFI::AutoPointer.new(result[:local_node_pointer], FFI::method(:hakuban_local_node_drop))
|
57
65
|
end
|
58
66
|
|
67
|
+
def with_default_serializer(&block)
|
68
|
+
@default_serializer = block
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
def with_default_deserializer(&block)
|
73
|
+
@default_deserializer = block
|
74
|
+
self
|
75
|
+
end
|
76
|
+
|
77
|
+
def default_serializer(&block)
|
78
|
+
if block_given?
|
79
|
+
@default_serializer = block
|
80
|
+
else
|
81
|
+
@default_serializer
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def default_deserializer(&block)
|
86
|
+
if block_given?
|
87
|
+
@default_deserializer = block
|
88
|
+
else
|
89
|
+
@default_deserializer
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
59
93
|
def object(tags, descriptor)
|
60
94
|
#TODO: accept real descriptor too
|
61
|
-
ObjectBuilder.new(self, ObjectDescriptor.new(tags,descriptor))
|
95
|
+
ObjectBuilder.new(self, ObjectDescriptor.new(tags,descriptor), @default_serializer, @default_deserializer)
|
62
96
|
end
|
63
97
|
|
64
98
|
def tag(descriptor)
|
65
99
|
#TODO: accept real descriptor too
|
66
|
-
TagBuilder.new(self, TagDescriptor.new(descriptor))
|
100
|
+
TagBuilder.new(self, TagDescriptor.new(descriptor), @default_serializer, @default_deserializer)
|
67
101
|
end
|
68
102
|
|
69
103
|
end
|
@@ -71,16 +105,24 @@ module Hakuban
|
|
71
105
|
|
72
106
|
class ObjectBuilder
|
73
107
|
|
74
|
-
def initialize(store, descriptor)
|
75
|
-
@store, @descriptor = store, descriptor
|
108
|
+
def initialize(store, descriptor, serializer, deserializer)
|
109
|
+
@store, @descriptor, @serializer, @deserializer = store, descriptor, serializer, deserializer
|
76
110
|
end
|
77
111
|
|
78
112
|
def observe
|
79
|
-
ObjectObserve.new(@store, @descriptor)
|
113
|
+
ObjectObserve.new(@store, @descriptor, @deserializer)
|
80
114
|
end
|
81
115
|
|
82
116
|
def expose
|
83
|
-
ObjectExpose.new(@store, @descriptor)
|
117
|
+
ObjectExpose.new(@store, @descriptor, @serializer)
|
118
|
+
end
|
119
|
+
|
120
|
+
def with_serializer(&block)
|
121
|
+
@serializer = block
|
122
|
+
end
|
123
|
+
|
124
|
+
def with_deserializer(&block)
|
125
|
+
@deserializer = block
|
84
126
|
end
|
85
127
|
|
86
128
|
end
|
@@ -88,16 +130,24 @@ module Hakuban
|
|
88
130
|
|
89
131
|
class TagBuilder
|
90
132
|
|
91
|
-
def initialize(store, descriptor)
|
92
|
-
@store, @descriptor = store, descriptor
|
133
|
+
def initialize(store, descriptor, serializer, deserializer)
|
134
|
+
@store, @descriptor, @serializer, @deserializer = store, descriptor, serializer, deserializer
|
93
135
|
end
|
94
136
|
|
95
137
|
def observe
|
96
|
-
TagObserve.new(@store, @descriptor)
|
138
|
+
TagObserve.new(@store, @descriptor, @deserializer)
|
97
139
|
end
|
98
140
|
|
99
141
|
def expose
|
100
|
-
TagExpose.new(@store, @descriptor)
|
142
|
+
TagExpose.new(@store, @descriptor, @serializer)
|
143
|
+
end
|
144
|
+
|
145
|
+
def with_serializer(&block)
|
146
|
+
@serializer = block
|
147
|
+
end
|
148
|
+
|
149
|
+
def with_deserializer(&block)
|
150
|
+
@deserializer = block
|
101
151
|
end
|
102
152
|
|
103
153
|
end
|
@@ -200,8 +250,8 @@ module Hakuban
|
|
200
250
|
|
201
251
|
attr_reader :descriptor
|
202
252
|
|
203
|
-
def initialize(local_node, descriptor)
|
204
|
-
@local_node, @descriptor = local_node, descriptor
|
253
|
+
def initialize(local_node, descriptor, deserializer)
|
254
|
+
@local_node, @descriptor, @deserializer = local_node, descriptor, deserializer
|
205
255
|
result = FFI::hakuban_object_observe_new(@local_node.local_node_pointer, descriptor.to_ffi)
|
206
256
|
Hakuban::raise_if_error(result)
|
207
257
|
@object_observe_pointer = ::FFI::AutoPointer.new(result[:object_observe_pointer], FFI::method(:hakuban_object_observe_drop))
|
@@ -210,7 +260,7 @@ module Hakuban
|
|
210
260
|
|
211
261
|
def object_state
|
212
262
|
raise "Attempt to use after 'drop'" if not @object_observe_pointer
|
213
|
-
ObjectObserveState.new(FFI::hakuban_object_observe_state_borrow(@object_observe_pointer))
|
263
|
+
ObjectObserveState.new(FFI::hakuban_object_observe_state_borrow(@object_observe_pointer), @deserializer)
|
214
264
|
end
|
215
265
|
|
216
266
|
def send_events_to(queue, *prefix)
|
@@ -250,19 +300,18 @@ module Hakuban
|
|
250
300
|
|
251
301
|
attr_reader :descriptor
|
252
302
|
|
253
|
-
def initialize(local_node, descriptor)
|
254
|
-
@local_node, @descriptor = local_node, descriptor
|
303
|
+
def initialize(local_node, descriptor, serializer)
|
304
|
+
@local_node, @descriptor, @serializer = local_node, descriptor, serializer
|
255
305
|
result = FFI::hakuban_object_expose_new(@local_node.local_node_pointer, descriptor.to_ffi)
|
256
306
|
Hakuban::raise_if_error(result)
|
257
307
|
@object_expose_pointer = ::FFI::AutoPointer.new(result[:object_expose_pointer], FFI::method(:hakuban_object_expose_drop))
|
258
308
|
@queues = {}
|
259
309
|
end
|
260
310
|
|
261
|
-
def set_object_state(version,
|
311
|
+
def set_object_state(version, data, data_type = [])
|
262
312
|
raise "Attempt to use after 'drop'" if not @object_expose_pointer
|
263
|
-
|
264
|
-
|
265
|
-
result = FFI::hakuban_object_expose_state(@object_expose_pointer, FFI::FFIObjectExposeState.construct(version, data_type, serialized))
|
313
|
+
serialized_data_type, serialized_data = @serializer.call(data_type, data)
|
314
|
+
result = FFI::hakuban_object_expose_state(@object_expose_pointer, FFI::FFIObjectExposeState.construct(version, serialized_data_type, serialized_data))
|
266
315
|
Hakuban::raise_if_error(result)
|
267
316
|
result[:changed] == 1
|
268
317
|
end
|
@@ -309,12 +358,12 @@ module Hakuban
|
|
309
358
|
|
310
359
|
attr_reader :data, :data_type, :data_version, :synchronized
|
311
360
|
|
312
|
-
def initialize(raw_state)
|
361
|
+
def initialize(raw_state, deserializer)
|
313
362
|
@raw_state = raw_state
|
314
363
|
@synchronized = (raw_state[:synchronized] == 1)
|
315
|
-
@data_type = raw_state[:data_type].read_array_of_pointer(raw_state[:data_type_length]).map { |string| string.read_string() }
|
316
364
|
@data_version = raw_state[:version].read_array_of_type(::FFI::TYPE_INT64, :read_int64, raw_state[:version_length]) if not raw_state[:version].null?
|
317
|
-
|
365
|
+
serialized_data_type = raw_state[:data_type].read_array_of_pointer(raw_state[:data_type_length]).map { |string| string.read_string() }
|
366
|
+
@data_type, @data = deserializer.call(serialized_data_type, raw_state[:raw].read_string_length(raw_state[:raw_length])) if not raw_state[:raw].null?
|
318
367
|
ObjectSpace.define_finalizer(self, ObjectObserveState.finalize(@raw_state))
|
319
368
|
end
|
320
369
|
|
@@ -339,8 +388,8 @@ module Hakuban
|
|
339
388
|
|
340
389
|
attr_reader :descriptor
|
341
390
|
|
342
|
-
def initialize(local_node, descriptor)
|
343
|
-
@local_node, @descriptor = local_node, descriptor
|
391
|
+
def initialize(local_node, descriptor, deserializer)
|
392
|
+
@local_node, @descriptor, @deserializer = local_node, descriptor, deserializer
|
344
393
|
result = FFI::hakuban_tag_observe_new(@local_node.local_node_pointer, @descriptor.to_ffi)
|
345
394
|
Hakuban::raise_if_error(result)
|
346
395
|
@tag_observe_pointer = ::FFI::AutoPointer.new(result[:tag_observe_pointer], FFI::method(:hakuban_tag_observe_drop))
|
@@ -360,7 +409,7 @@ module Hakuban
|
|
360
409
|
result = FFI::hakuban_tag_observe_object_state_borrow(@tag_observe_pointer, object_descriptor.to_ffi)
|
361
410
|
return nil if result[:error] == 4
|
362
411
|
Hakuban::raise_if_error(result)
|
363
|
-
ObjectObserveState.new(result[:state])
|
412
|
+
ObjectObserveState.new(result[:state], @deserializer)
|
364
413
|
end
|
365
414
|
|
366
415
|
def send_events_to(*params)
|
@@ -400,8 +449,8 @@ module Hakuban
|
|
400
449
|
|
401
450
|
attr_reader :descriptor
|
402
451
|
|
403
|
-
def initialize(local_node, descriptor)
|
404
|
-
@local_node, @descriptor = local_node, descriptor
|
452
|
+
def initialize(local_node, descriptor, serializer)
|
453
|
+
@local_node, @descriptor, @serializer = local_node, descriptor, serializer
|
405
454
|
result = FFI::hakuban_tag_expose_new(@local_node.local_node_pointer, descriptor.to_ffi)
|
406
455
|
Hakuban::raise_if_error(result)
|
407
456
|
@tag_expose_pointer = ::FFI::AutoPointer.new(result[:tag_expose_pointer], FFI::method(:hakuban_tag_expose_drop))
|
@@ -416,11 +465,10 @@ module Hakuban
|
|
416
465
|
ret
|
417
466
|
end
|
418
467
|
|
419
|
-
def set_object_state(object_descriptor, version,
|
468
|
+
def set_object_state(object_descriptor, version, data, data_type = [])
|
420
469
|
raise "Attempt to use after 'drop'" if not @tag_expose_pointer
|
421
|
-
|
422
|
-
|
423
|
-
result = FFI::hakuban_tag_expose_object_state(@tag_expose_pointer, object_descriptor.to_ffi, FFI::FFIObjectExposeState.construct(version, data_type, serialized))
|
470
|
+
serialized_data_type, serialized_data = @serializer.call(data_type, data)
|
471
|
+
result = FFI::hakuban_tag_expose_object_state(@tag_expose_pointer, object_descriptor.to_ffi, FFI::FFIObjectExposeState.construct(version, serialized_data_type, serialized_data))
|
424
472
|
Hakuban::raise_if_error(result)
|
425
473
|
result[:changed] == 1
|
426
474
|
end
|
@@ -487,12 +535,6 @@ module Hakuban
|
|
487
535
|
@websocket_connector_pointer = ::FFI::AutoPointer.new(result[:websocket_connector_pointer], WebsocketConnector.generate_drop)
|
488
536
|
end
|
489
537
|
|
490
|
-
def start(local_node)
|
491
|
-
@local_node = local_node
|
492
|
-
FFI::hakuban_tokio_websocket_connector_start(Tokio.pointer, @websocket_connector_pointer, @local_node.local_node_pointer)
|
493
|
-
self
|
494
|
-
end
|
495
|
-
|
496
538
|
def self.generate_drop
|
497
539
|
proc { |pointer|
|
498
540
|
FFI::hakuban_tokio_websocket_connector_drop(Tokio.pointer, pointer)
|
@@ -504,7 +546,7 @@ module Hakuban
|
|
504
546
|
|
505
547
|
# convenience utils
|
506
548
|
|
507
|
-
#TODO: replace this mess (<Hash, dynamic
|
549
|
+
#TODO: replace this mess (<Hash, dynamic mixins) with some "deref"
|
508
550
|
class ObjectManager < Hash
|
509
551
|
|
510
552
|
module ObservedObjectManager
|
@@ -594,10 +636,11 @@ module Hakuban
|
|
594
636
|
end
|
595
637
|
|
596
638
|
|
597
|
-
class ManagedObject
|
639
|
+
class ManagedObject < OpenStruct
|
598
640
|
attr_reader :contract, :descriptor
|
599
641
|
def initialize(contract, descriptor)
|
600
642
|
@contract, @descriptor = contract, descriptor
|
643
|
+
super()
|
601
644
|
end
|
602
645
|
end
|
603
646
|
|
@@ -621,7 +664,7 @@ module Hakuban
|
|
621
664
|
|
622
665
|
class ExposedObject < ManagedObject
|
623
666
|
def state_set(state)
|
624
|
-
if @contract.method(:set_object_state).arity == 4
|
667
|
+
if @contract.method(:set_object_state).arity == -4
|
625
668
|
@contract.set_object_state(@descriptor, *state)
|
626
669
|
else
|
627
670
|
@contract.set_object_state(*state)
|
@@ -632,10 +675,10 @@ module Hakuban
|
|
632
675
|
end
|
633
676
|
def data_set(value)
|
634
677
|
timestamp = Time.new.to_f
|
635
|
-
if @contract.method(:set_object_state).arity == 4
|
636
|
-
@contract.set_object_state(@descriptor,[1, timestamp.floor, ((timestamp - timestamp.floor)*1000000000).floor, 0],
|
678
|
+
if @contract.method(:set_object_state).arity == -4
|
679
|
+
@contract.set_object_state(@descriptor,[1, timestamp.floor, ((timestamp - timestamp.floor)*1000000000).floor, 0],value)
|
637
680
|
else
|
638
|
-
@contract.set_object_state([1, timestamp.floor, ((timestamp - timestamp.floor)*1000000000).floor, 0],
|
681
|
+
@contract.set_object_state([1, timestamp.floor, ((timestamp - timestamp.floor)*1000000000).floor, 0],value)
|
639
682
|
end
|
640
683
|
end
|
641
684
|
def data=(value)
|
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.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yunta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|