hakuban 0.5.2 → 0.5.3

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