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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79890c306cc3df4c9d3382773a66d38fa6373c6f1c2c874301ba0409050ab20d
4
- data.tar.gz: e17ffc0520c6605a3cb2b207de58fc98c19d3c8d2472adf681a99dcbcb48b450
3
+ metadata.gz: 7b1dd3c0a54ced0edb0c409842cb7d74ca6cadf8472ad6b7e15fec97198ef8ad
4
+ data.tar.gz: 228080f7a28f5718620a30af69cb4c277682508623937684fb961e0994b50a91
5
5
  SHA512:
6
- metadata.gz: a243af479fa4f47245696cb408498ce37fb46c4ca03563fc7b648dbec40cc0a18c76d227358f1dc36a1c66c31f102dc042fcf162168210b8d87f863230f4bf3f
7
- data.tar.gz: ef2eec57f61f45da32b363e9b77b6cdda3de545b82ff5fce506f5970509b998b195d229625ca590e496b2679cd7fc18da61497a478226cf69b73c04be136189d
6
+ metadata.gz: 8afdbc65c6eee3ff1d4475f89b12b88f72c970eb37890aff2e66fcbba2ccac5b5cc897859aa8eedb727f6b484d999875f83176cc34698788d64f72bd96b4e577
7
+ data.tar.gz: c67bbfc8d9e3205973f33d5041fb71c642a41667156feadea39fed0bda72f1a0734912be440ee8b5cb4a6c83dff6d28da3ae36ee34ed76caee791ff80e3ffff8
@@ -2,15 +2,10 @@ require 'hakuban'
2
2
  require_relative './cpu-usage.rb'
3
3
 
4
4
 
5
- class Utilization < Hakuban::ObjectManager::ManagedObject
6
- include Hakuban::ObjectManager::ObservedObject
7
- include Hakuban::ObjectManager::ExposedObject
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").start(hakuban)
22
- all_utilizations = hakuban.tag("utilizations").observe.manage(Utilization)
23
- my_utilization = hakuban.object(["utilizations"],{id: id}).expose.manage(Utilization)
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 = [cpu_usage]
23
+ my_utilization.data = {"percentage"=>cpu_usage} if cpu_usage
29
24
 
30
- utilizations = all_utilizations.objects.values.sort_by(&:id).map { |utilization|
31
- [utilization.id, utilization.data&.first]
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
 
@@ -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").start(hakuban)
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],[],[cpu_usage]) if cpu_usage
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.first}"
20
+ puts "#{descriptor.json["id"]} -> #{data["percentage"]}"
21
21
  end
22
22
  }
23
23
 
@@ -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, data_type, data)
311
+ def set_object_state(version, data, data_type = [])
262
312
  raise "Attempt to use after 'drop'" if not @object_expose_pointer
263
- data_type = ["MessagePack"] + data_type
264
- serialized = MessagePack.pack(data)
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
- @data = MessagePack.unpack(raw_state[:raw].read_string_length(raw_state[:raw_length])) if not raw_state[:raw].null?
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, data_type, data)
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
- data_type = ["MessagePack"] + data_type
422
- serialized = MessagePack.pack(data)
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 mixings) with some "deref"
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],[],value)
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],[],value)
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hakuban
4
- VERSION = "0.5.2"
4
+ VERSION = "0.5.3"
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.5.2
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 00:00:00.000000000 Z
11
+ date: 2021-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec