hakuban 0.5.1 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -0
- data/bin/hakuban-observer +56 -0
- data/bin/hakuban-thread-engine +45 -0
- data/lib/hakuban/async.rb +45 -0
- data/lib/hakuban/engine.rb +44 -0
- data/lib/hakuban/ffi.rb +36 -18
- data/lib/hakuban/hakuban.rb +175 -295
- data/lib/hakuban/manager.rb +259 -0
- data/lib/hakuban/thread.rb +44 -0
- data/lib/hakuban/version.rb +1 -1
- data/lib/hakuban.rb +3 -0
- metadata +21 -22
- data/.gitignore +0 -12
- data/.rspec +0 -3
- data/Gemfile +0 -6
- data/LICENSE.txt +0 -21
- data/bin/console +0 -15
- data/bin/setup +0 -8
- data/examples/all-top-managed.rb +0 -46
- data/examples/all-top-simple.rb +0 -26
- data/examples/cpu-usage.rb +0 -16
- data/hakuban.gemspec +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f12beca62a4975af1ee3f85d5ec83e85753a6f6bb95fb36529c284d88eba41c5
|
4
|
+
data.tar.gz: ca7a3c890c4ba1b7dc337ac1e3120b8d5d260c8170f641493067b5f75060c3ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb3e86f190c140edb9658f42f33cb9bfdad718cb6b04a9f1bced7240ed2b64716d43ab651f3551b4ee084d103fdfc3bf038dc7e3f91332f1bac692e5b9b7001f
|
7
|
+
data.tar.gz: fd40ec84a8e7f713f857768e84dd0f5554beb00adf586adf7e739e12e1920cb568387df5cc8c4085c7bec83fbffc36a5d16bbe7211481774e849b5dda402fab6
|
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
|
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
|
30
|
-
layout :
|
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,
|
68
|
+
layout :error, :uint8, :state, :pointer
|
62
69
|
end
|
63
70
|
|
64
71
|
class FFIObjectDescriptor < FFI::Struct
|
@@ -118,38 +125,49 @@ module Hakuban::FFI
|
|
118
125
|
#callback :tag_callback, [ :pointer, FFITagDescriptor.by_value, :uint8 ], :void
|
119
126
|
|
120
127
|
attach_function :hakuban_local_node_new, [ :string ], FFILocalNodeNewResult.by_value
|
121
|
-
attach_function :hakuban_local_node_drop, [ :pointer ], :void
|
128
|
+
attach_function :hakuban_local_node_drop, [ :pointer ], :void, blocking: true
|
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 ],
|
126
|
-
attach_function :
|
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 :
|
132
|
-
attach_function :
|
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 :
|
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 :
|
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, [
|
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
|
152
|
-
attach_function :hakuban_tokio_websocket_connector_drop, [ :pointer, :pointer ], :void
|
170
|
+
attach_function :hakuban_tokio_websocket_connector_drop, [ :pointer, :pointer ], :void, blocking: true
|
153
171
|
|
154
172
|
attach_function :hakuban_logger_initialize, [ :string ], :uint8
|
155
173
|
|