hakuban 0.5.2 → 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: 79890c306cc3df4c9d3382773a66d38fa6373c6f1c2c874301ba0409050ab20d
4
- data.tar.gz: e17ffc0520c6605a3cb2b207de58fc98c19d3c8d2472adf681a99dcbcb48b450
3
+ metadata.gz: 6d0b0d54e3b6dce8ecd11b991e94768247f2e978cca397d430fcab6bfd987484
4
+ data.tar.gz: 81466178ba54513cb665cd49800599125bda1ba108f7eee71efff3e5b496cbb5
5
5
  SHA512:
6
- metadata.gz: a243af479fa4f47245696cb408498ce37fb46c4ca03563fc7b648dbec40cc0a18c76d227358f1dc36a1c66c31f102dc042fcf162168210b8d87f863230f4bf3f
7
- data.tar.gz: ef2eec57f61f45da32b363e9b77b6cdda3de545b82ff5fce506f5970509b998b195d229625ca590e496b2679cd7fc18da61497a478226cf69b73c04be136189d
6
+ metadata.gz: dc7157372663dc871a85b36ee042e0fc12b66ad45fb322398b593086b47896167ab4cb913ab8b1f636071a9a006d2a3ab3af34b6d32e4024d7f3121dc4d9e19c
7
+ data.tar.gz: 6b0b7c59f66be811b16322574f8f0670c5802760b8cf8e690b3d4fa4107ea17dffa1e085c0c9607a72fa0a025eef0665087d5b18b0d671e43bab1cf7b5eea95f
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015-2021 yunta
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,56 @@
1
+ #!/bin/env ruby
2
+
3
+ require 'slop'
4
+ require 'pp'
5
+ require 'hakuban/async'
6
+
7
+
8
+ OPTIONS = Slop.parse { |o|
9
+ o.string '-c', '--connect', "Hakuban upstream address (default: ws://127.0.0.1:3001)", default: "ws://127.0.0.1:3001"
10
+ o.string '-o', '--object', "Object descriptor"
11
+ o.array '-t', '--tag', "Tag descriptor(s)"
12
+ o.bool '-d', '--debug', 'Show debug messages'
13
+ o.on '-h', '--help' do puts o; exit end
14
+ }
15
+
16
+ Hakuban.logger_initialize("hakuban=debug") if OPTIONS.debug?
17
+ hakuban = Hakuban::LocalNode.new(name: OPTIONS["name"])
18
+ connector = Hakuban::WebsocketConnector.new(hakuban, OPTIONS["connect"])
19
+
20
+ observe_contract = if OPTIONS["object"]
21
+ json = JSON.load(OPTIONS["object"])
22
+ tags = OPTIONS["tag"].map { |tag| JSON.load(tag) }
23
+ hakuban.object(tags, json).observe
24
+ else
25
+ tag = OPTIONS["tag"].map { |tag| JSON.load(tag) }
26
+ hakuban.tag(tag[0]).observe
27
+ end
28
+
29
+
30
+ def print_event(descriptor, event)
31
+ puts "-"*120
32
+ puts "Event: " + event
33
+ puts "Descriptor: "
34
+ descriptor.tags.each { |tag|
35
+ puts "\tTags: " + JSON.dump(tag.json)
36
+ }
37
+ puts "\tJSON: " + JSON.dump(descriptor.json)
38
+ end
39
+
40
+ Async {
41
+
42
+ observe_contract.async { |object|
43
+ print_event(object.descriptor, "create")
44
+ while object.next_change
45
+ print_event(object.descriptor, "change")
46
+ if state = object.state
47
+ puts "Version: " + state.version.inspect
48
+ puts "Last synchronized: " + state.synchronized.to_s + "ms ago"
49
+ puts "Data:\n"
50
+ pp state.data
51
+ end
52
+ end
53
+ print_event(object.descriptor, "drop")
54
+ }
55
+
56
+ }
@@ -0,0 +1,45 @@
1
+ #!/bin/env ruby
2
+
3
+ require 'slop'
4
+ require 'hakuban/thread'
5
+ require 'socket'
6
+
7
+ STDOUT.sync = true
8
+
9
+
10
+ OPTIONS = Slop.parse { |o|
11
+ o.string '-c', '--connect', "Hakuban upstream address (default: ws://127.0.0.1:3001)", default: "ws://127.0.0.1:3001"
12
+ o.string '-n', '--name', "Node name (default: engine-PID)", default: "engine##{$$}@#{Socket.gethostname}"
13
+ o.array '-e', '--engines', "engines to start, a glob pattern matched against class name (default: *)", delimiter: ",", default: ["*"]
14
+ o.bool '-d', '--debug', 'Show debug messages'
15
+ o.on '-h', '--help' do puts o; exit end
16
+ }
17
+
18
+
19
+ Hakuban.logger_initialize("hakuban=debug") if OPTIONS.debug?
20
+ $hakuban = Hakuban::LocalNode.new(name: OPTIONS["name"])
21
+ connector = Hakuban::WebsocketConnector.new($hakuban, OPTIONS["connect"])
22
+
23
+
24
+ OPTIONS.arguments.each { |to_require|
25
+ require to_require
26
+ }
27
+
28
+ started_engines = OPTIONS[:engines].map { |engine_name_pattern|
29
+ Hakuban::Engine.engines.select { |engine_class|
30
+ File.fnmatch(engine_name_pattern, engine_class.name)
31
+ }
32
+ }.flatten.uniq.map { |engine_class|
33
+ engine_class.new
34
+ }.each { |engine|
35
+ engine.start($hakuban)
36
+ puts "Started engine: #{engine.class.name}"
37
+ }
38
+
39
+ sleep
40
+
41
+ started_engines.each { |engine|
42
+ engine.stop
43
+ puts "Stopped engine: #{engine.class.name}"
44
+ }
45
+
@@ -0,0 +1,45 @@
1
+ require 'hakuban'
2
+ require 'hakuban/manager'
3
+ require 'async'
4
+
5
+ module Hakuban
6
+
7
+ class AsyncObjectManager < ObjectManager
8
+ def async_run
9
+ Async { yield }
10
+ end
11
+
12
+ def async_join(async)
13
+ async.wait
14
+ end
15
+ end
16
+
17
+
18
+ class ObjectObserve
19
+ def async(&block)
20
+ AsyncObjectManager.new(self, ObservedObject, block)
21
+ end
22
+ end
23
+
24
+
25
+ class ObjectExpose
26
+ def async(&block)
27
+ AsyncObjectManager.new(self, ExposedObject, block)
28
+ end
29
+ end
30
+
31
+
32
+ class TagObserve
33
+ def async(&block)
34
+ AsyncObjectManager.new(self, ObservedObject, block)
35
+ end
36
+ end
37
+
38
+
39
+ class TagExpose
40
+ def async(&block)
41
+ AsyncObjectManager.new(self, ExposedObject, block)
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,44 @@
1
+ module Hakuban
2
+
3
+ class Engine
4
+
5
+ def initialize
6
+ raise "Hakuban::Engine is abstract" if self.class == Hakuban::Engine
7
+ @contracts = []
8
+ end
9
+
10
+
11
+ def start(hakuban)
12
+ @contracts.concat([init(hakuban)])
13
+ @contracts.flatten!
14
+ @contracts.compact!
15
+ @contracts.uniq!
16
+ end
17
+
18
+ def init(hakuban)
19
+ raise "Hakuban::Engine::init is a pure virtual function, descendants should bring their own implementation"
20
+ end
21
+
22
+ def stop
23
+ @contracts.each { |contract|
24
+ contract.drop
25
+ }
26
+ end
27
+
28
+
29
+
30
+ @@descendants = []
31
+
32
+
33
+ def self.engines
34
+ @@descendants
35
+ end
36
+
37
+
38
+ def self.inherited(subclass)
39
+ @@descendants << subclass
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -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/ffi.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'json'
2
2
  require 'ffi'
3
- require 'msgpack'
4
3
 
5
4
 
6
5
  # all functions which can trigger synchronuous callbacks, and those which wait on rust locks are "blocking: true" to avoid deadlock on GIL
@@ -26,10 +25,18 @@ module Hakuban::FFI
26
25
  layout :error, :uint8, :tag_expose_pointer, :pointer
27
26
  end
28
27
 
29
- class FFIObjectObserveState < FFI::Struct
30
- layout :synchronized, :uint8, :version_length, :size_t, :version, :pointer, :data_type_length, :size_t, :data_type, :pointer, :raw_length, :size_t, :raw, :pointer, :raw_arc, :pointer
28
+ class FFIObjectObserveStateGetVersionResult < FFI::Struct
29
+ layout :version_length, :size_t, :version_elements, :pointer
31
30
  end
32
-
31
+
32
+ class FFIObjectObserveStateGetDataTypeResult < FFI::Struct
33
+ layout :type_length, :size_t, :type_elements, :pointer
34
+ end
35
+
36
+ class FFIObjectObserveStateGetDataResult < FFI::Struct
37
+ layout :data_length, :size_t, :data_bytes, :pointer
38
+ end
39
+
33
40
  class FFIObjectExposeState < FFI::Struct
34
41
  layout :version_length, :size_t, :version, :pointer, :data_type_length, :size_t, :data_type, :pointer, :raw_length, :size_t, :raw, :pointer
35
42
  attr_accessor :data_type_strings
@@ -58,7 +65,7 @@ module Hakuban::FFI
58
65
  end
59
66
 
60
67
  class FFITagObserveObjectStateBorrowResult < FFI::Struct
61
- layout :error, :uint8, :state, FFIObjectObserveState.by_value
68
+ layout :error, :uint8, :state, :pointer
62
69
  end
63
70
 
64
71
  class FFIObjectDescriptor < FFI::Struct
@@ -122,30 +129,41 @@ module Hakuban::FFI
122
129
 
123
130
  attach_function :hakuban_object_observe_new, [ :pointer, FFIObjectDescriptor.by_value ], FFIObjectObserveResult.by_value, blocking: true
124
131
  attach_function :hakuban_object_observe_drop, [ :pointer ], :void, blocking: true
125
- attach_function :hakuban_object_observe_state_borrow, [ :pointer ], FFIObjectObserveState.by_value, blocking: true
126
- attach_function :hakuban_object_observe_changes_callback_register, [ :pointer, :object_callback, :pointer ], :pointer, blocking: true
127
-
132
+ attach_function :hakuban_object_observe_state_borrow, [ :pointer ], :pointer, blocking: true
133
+ attach_function :hakuban_object_observe_events_get, [ :pointer ], :pointer, blocking: true
134
+
128
135
  attach_function :hakuban_object_expose_new, [ :pointer, FFIObjectDescriptor.by_value], FFIObjectExposeResult.by_value, blocking: true
129
136
  attach_function :hakuban_object_expose_drop, [ :pointer ], :void, blocking: true
130
- attach_function :hakuban_object_expose_state, [ :pointer, FFIObjectExposeState.by_value ], FFIObjectExposeStateResult.by_value, blocking: true
131
- attach_function :hakuban_object_expose_assigned, [ :pointer ], :uint8, blocking: true
132
- attach_function :hakuban_object_expose_changes_callback_register, [ :pointer, :object_callback, :pointer ], :pointer, blocking: true
137
+ attach_function :hakuban_object_expose_state, [ :pointer, FFIObjectExposeState.by_value, :uint64 ], FFIObjectExposeStateResult.by_value, blocking: true
138
+ attach_function :hakuban_object_expose_assignment, [ :pointer ], :uint64, blocking: true
139
+ attach_function :hakuban_object_expose_desynchronize, [ :pointer, :uint64 ], :void, blocking: true
140
+ attach_function :hakuban_object_expose_events_get, [ :pointer ], :pointer, blocking: true
133
141
 
134
142
  attach_function :hakuban_tag_observe_new, [ :pointer, FFITagDescriptor.by_value ], FFITagObserveResult.by_value, blocking: true
135
143
  attach_function :hakuban_tag_observe_drop, [ :pointer ], :void, blocking: true
136
144
  attach_function :hakuban_tag_observe_object_descriptors_borrow, [ :pointer ], FFIObjectDescriptors.by_value, blocking: true
137
145
  attach_function :hakuban_tag_observe_object_state_borrow, [ :pointer, FFIObjectDescriptor.by_value ], FFITagObserveObjectStateBorrowResult.by_value, blocking: true
138
- attach_function :hakuban_tag_observe_objects_changes_callback_register, [ :pointer, :object_callback, :pointer ], :pointer, blocking: true
146
+ attach_function :hakuban_tag_observe_events_get, [ :pointer ], :pointer, blocking: true
139
147
 
140
148
  attach_function :hakuban_tag_expose_new, [ :pointer, FFITagDescriptor.by_value ], FFITagExposeResult.by_value, blocking: true
141
149
  attach_function :hakuban_tag_expose_drop, [ :pointer ], :void, blocking: true
142
150
  attach_function :hakuban_tag_expose_object_descriptors_borrow, [ :pointer ], FFIObjectDescriptors.by_value, blocking: true
143
- attach_function :hakuban_tag_expose_object_state, [ :pointer, FFIObjectDescriptor.by_value, FFIObjectExposeState.by_value ], FFIObjectExposeStateResult.by_value, blocking: true
144
- attach_function :hakuban_tag_expose_objects_changes_callback_register, [ :pointer, :object_callback, :pointer ], :pointer, blocking: true
151
+ attach_function :hakuban_tag_expose_object_state, [ :pointer, FFIObjectDescriptor.by_value, FFIObjectExposeState.by_value, :uint64 ], FFIObjectExposeStateResult.by_value, blocking: true
152
+ attach_function :hakuban_tag_expose_object_assignment, [ :pointer, FFIObjectDescriptor.by_value ], :uint64, blocking: true
153
+ attach_function :hakuban_tag_expose_object_desynchronize, [ :pointer, FFIObjectDescriptor.by_value, :uint64 ], :void, blocking: true
154
+ attach_function :hakuban_tag_expose_events_get, [ :pointer ], :pointer, blocking: true
155
+
156
+ attach_function :hakuban_object_observe_state_get_synchronized, [ :pointer ], :uint64
157
+ attach_function :hakuban_object_observe_state_get_data_version, [ :pointer ], FFIObjectObserveStateGetVersionResult.by_value
158
+ attach_function :hakuban_object_observe_state_get_data_type, [ :pointer ], FFIObjectObserveStateGetDataTypeResult.by_value
159
+ attach_function :hakuban_object_observe_state_get_data, [ :pointer ], FFIObjectObserveStateGetDataResult.by_value
160
+
161
+ attach_function :hakuban_object_descriptor_events_callback_register, [ :pointer, :object_callback, :pointer ], :pointer, blocking: true
162
+ attach_function :hakuban_object_descriptor_events_callback_unregister, [ :pointer ], :void, blocking: true
163
+ attach_function :hakuban_object_descriptor_events_return, [ :pointer ], :void, blocking: true
145
164
 
146
- attach_function :hakuban_object_observe_state_return, [ FFIObjectObserveState.by_value ], :void
165
+ attach_function :hakuban_object_observe_state_return, [ :pointer ], :void
147
166
  attach_function :hakuban_object_descriptors_return, [ FFIObjectDescriptors.by_value ], :void
148
- attach_function :hakuban_object_callback_unregister, [ :pointer ], :void, blocking: true
149
167
 
150
168
  attach_function :hakuban_tokio_init_multi_thread, [ :size_t ], :pointer
151
169
  attach_function :hakuban_tokio_websocket_connector_new, [ :pointer, :pointer, :string ], FFITokioWebsocketConnectorNewResult.by_value