sumac 0.0.0
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 +7 -0
- data/LICENSE +201 -0
- data/README.md +2 -0
- data/lib/core_extensions.rb +207 -0
- data/lib/sumac.rb +94 -0
- data/lib/sumac/adapter.rb +5 -0
- data/lib/sumac/adapter/closed.rb +7 -0
- data/lib/sumac/argument_error.rb +5 -0
- data/lib/sumac/call_dispatcher.rb +70 -0
- data/lib/sumac/call_processor.rb +93 -0
- data/lib/sumac/closed_error.rb +5 -0
- data/lib/sumac/closer.rb +53 -0
- data/lib/sumac/connection.rb +94 -0
- data/lib/sumac/exposed_object.rb +131 -0
- data/lib/sumac/exposed_object_child.rb +158 -0
- data/lib/sumac/forgoten.rb +5 -0
- data/lib/sumac/handshake.rb +48 -0
- data/lib/sumac/id_allocator.rb +99 -0
- data/lib/sumac/local_reference.rb +16 -0
- data/lib/sumac/local_references.rb +80 -0
- data/lib/sumac/message.rb +19 -0
- data/lib/sumac/message/exchange.rb +30 -0
- data/lib/sumac/message/exchange/base.rb +15 -0
- data/lib/sumac/message/exchange/call_request.rb +96 -0
- data/lib/sumac/message/exchange/call_response.rb +83 -0
- data/lib/sumac/message/exchange/compatibility_notification.rb +53 -0
- data/lib/sumac/message/exchange/forget_notification.rb +77 -0
- data/lib/sumac/message/exchange/id.rb +30 -0
- data/lib/sumac/message/exchange/initialization_notification.rb +52 -0
- data/lib/sumac/message/exchange/notification.rb +9 -0
- data/lib/sumac/message/exchange/shutdown_notification.rb +27 -0
- data/lib/sumac/message/object.rb +72 -0
- data/lib/sumac/message/object/array.rb +57 -0
- data/lib/sumac/message/object/base.rb +21 -0
- data/lib/sumac/message/object/boolean.rb +45 -0
- data/lib/sumac/message/object/exception.rb +66 -0
- data/lib/sumac/message/object/exposed.rb +79 -0
- data/lib/sumac/message/object/exposed_child.rb +86 -0
- data/lib/sumac/message/object/float.rb +45 -0
- data/lib/sumac/message/object/hash_table.rb +75 -0
- data/lib/sumac/message/object/integer.rb +45 -0
- data/lib/sumac/message/object/native_exception.rb +56 -0
- data/lib/sumac/message/object/null.rb +44 -0
- data/lib/sumac/message/object/string.rb +45 -0
- data/lib/sumac/message_error.rb +5 -0
- data/lib/sumac/messenger.rb +65 -0
- data/lib/sumac/native_error.rb +17 -0
- data/lib/sumac/no_method_error.rb +9 -0
- data/lib/sumac/reference.rb +68 -0
- data/lib/sumac/remote_entry.rb +42 -0
- data/lib/sumac/remote_object.rb +39 -0
- data/lib/sumac/remote_object_child.rb +38 -0
- data/lib/sumac/remote_reference.rb +16 -0
- data/lib/sumac/remote_references.rb +70 -0
- data/lib/sumac/scheduler.rb +56 -0
- data/lib/sumac/shutdown.rb +32 -0
- data/lib/sumac/stale_object_error.rb +5 -0
- data/lib/sumac/unexposable_object_error.rb +9 -0
- data/lib/sumac/worker_pool.rb +35 -0
- data/test/test_id_allocator.rb +25 -0
- metadata +145 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class Sumac
|
|
2
|
+
class RemoteObject < Object
|
|
3
|
+
|
|
4
|
+
def initialize(connection, remote_reference)
|
|
5
|
+
raise "argument 'connection' must be a Connection" unless connection.is_a?(Connection)
|
|
6
|
+
@connection = connection
|
|
7
|
+
raise unless remote_reference.is_a?(RemoteReference)
|
|
8
|
+
@remote_reference = remote_reference
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def method_missing(method_name, *arguments, &block) # blocks not working yet
|
|
12
|
+
@connection.mutex.lock
|
|
13
|
+
raise StaleObjectError unless @remote_reference.callable?
|
|
14
|
+
begin
|
|
15
|
+
arguments << block.to_lambda if block_given?
|
|
16
|
+
return_value = @connection.call_dispatcher.make_call(self, method_name.to_s, arguments)
|
|
17
|
+
rescue ClosedError
|
|
18
|
+
raise StaleObjectError
|
|
19
|
+
end
|
|
20
|
+
return_value
|
|
21
|
+
ensure
|
|
22
|
+
@connection.mutex.unlock if @connection.mutex.owned?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def __remote_reference__
|
|
26
|
+
@remote_reference
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def forget
|
|
30
|
+
@connection.mutex.synchronize { @remote_reference.local_forget_request }
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def inspect
|
|
35
|
+
"#<Sumac::RemoteObject:#{"0x00%x" % (object_id << 1)}>"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
class Sumac
|
|
2
|
+
class RemoteObjectChild < Object
|
|
3
|
+
|
|
4
|
+
def initialize(connection, parent, key)
|
|
5
|
+
raise "argument 'connection' must be a Connection" unless connection.is_a?(Connection)
|
|
6
|
+
@connection = connection
|
|
7
|
+
raise unless parent.is_a?(RemoteObject)
|
|
8
|
+
@parent = parent
|
|
9
|
+
@key = key
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def method_missing(method_name, *arguments, &block) # blocks not working yet
|
|
13
|
+
@connection.mutex.lock
|
|
14
|
+
begin
|
|
15
|
+
arguments << block.to_lambda if block_given?
|
|
16
|
+
return_value = @connection.call_dispatcher.make_call(self, method_name.to_s, arguments)
|
|
17
|
+
rescue ClosedError
|
|
18
|
+
raise StaleObjectError
|
|
19
|
+
end
|
|
20
|
+
return_value
|
|
21
|
+
ensure
|
|
22
|
+
@connection.mutex.unlock if @connection.mutex.owned?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def __key__
|
|
26
|
+
@key
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def __parent__
|
|
30
|
+
@parent
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def inspect
|
|
34
|
+
"#<Sumac::RemoteObjectChild:#{"0x00%x" % (object_id << 1)}>"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class Sumac
|
|
2
|
+
class RemoteReference < Reference
|
|
3
|
+
|
|
4
|
+
attr_reader :remote_object
|
|
5
|
+
|
|
6
|
+
def initialize(connection, exposed_id)
|
|
7
|
+
super(connection, exposed_id)
|
|
8
|
+
@remote_object = RemoteObject.new(@connection, self)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def remove
|
|
12
|
+
@connection.remote_references.remove(self)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
class Sumac
|
|
2
|
+
class RemoteReferences
|
|
3
|
+
|
|
4
|
+
def initialize(connection)
|
|
5
|
+
raise "argument 'connection' must be a Connection" unless connection.is_a?(Connection)
|
|
6
|
+
@connection = connection
|
|
7
|
+
@exposed_id_table = {}
|
|
8
|
+
@transaction = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def detach
|
|
12
|
+
each { |reference| reference.detach }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def destroy
|
|
16
|
+
each { |reference| reference.destroy }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def from_id(exposed_id)
|
|
20
|
+
raise unless IDAllocator.valid?(exposed_id)
|
|
21
|
+
reference = find(exposed_id) || create(exposed_id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def from_object(remote_object)
|
|
25
|
+
raise unless remote_object.is_a?(RemoteObject)
|
|
26
|
+
reference = remote_object.__remote_reference__
|
|
27
|
+
raise StaleObjectError unless reference.callable?
|
|
28
|
+
reference
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def remove(reference)
|
|
32
|
+
@exposed_id_table.delete(reference.exposed_id)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def rollback_transaction
|
|
36
|
+
@transaction.each { |reference| reference.quiet_forget }
|
|
37
|
+
@transaction = []
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def commit_transaction
|
|
41
|
+
@transaction = nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def start_transaction
|
|
45
|
+
@transaction = []
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def create(new_exposed_id)
|
|
51
|
+
new_reference = RemoteReference.new(@connection, new_exposed_id)
|
|
52
|
+
@exposed_id_table[new_exposed_id] = new_reference
|
|
53
|
+
@transaction << new_reference if @transaction
|
|
54
|
+
new_reference
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def find(exposed_id)
|
|
58
|
+
reference = @exposed_id_table[exposed_id]
|
|
59
|
+
return if reference && reference.stale?
|
|
60
|
+
reference
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def each
|
|
64
|
+
@exposed_id_table.values.each do |reference|
|
|
65
|
+
yield(reference) unless reference.stale?
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
class Sumac
|
|
2
|
+
class Scheduler
|
|
3
|
+
|
|
4
|
+
def initialize(connection, worker_count)
|
|
5
|
+
raise "argument 'connection' must be a Connection" unless connection.is_a?(Connection)
|
|
6
|
+
@connection = connection
|
|
7
|
+
@worker_pool = WorkerPool.new(worker_count)
|
|
8
|
+
@dispatch_worker = nil
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def run
|
|
12
|
+
@dispatch_worker = Thread.new do
|
|
13
|
+
@connection.mutex.synchronize do
|
|
14
|
+
raise unless @connection.at?(:initial)
|
|
15
|
+
@connection.to(:compatibility_handshake)
|
|
16
|
+
end
|
|
17
|
+
receiver_loop
|
|
18
|
+
end
|
|
19
|
+
nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def receiver_loop
|
|
23
|
+
loop do
|
|
24
|
+
begin
|
|
25
|
+
message_string = @connection.messenger_adapter.receive
|
|
26
|
+
rescue Adapter::ClosedError
|
|
27
|
+
@connection.mutex.synchronize do
|
|
28
|
+
unless @connection.at?([:kill, :close])
|
|
29
|
+
@connection.to(:kill)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
break if @connection.mutex.synchronize { @connection.at?([:kill, :close]) }
|
|
34
|
+
dispatch(message_string)
|
|
35
|
+
end
|
|
36
|
+
nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def dispatch(message_string)
|
|
40
|
+
#@worker_pool.run do
|
|
41
|
+
@connection.mutex.synchronize do
|
|
42
|
+
break if @connection.at?([:kill, :close])
|
|
43
|
+
@connection.messenger.receive(message_string)
|
|
44
|
+
end
|
|
45
|
+
#end
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def join
|
|
50
|
+
@dispatch_worker.join
|
|
51
|
+
@worker_pool.join
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class Sumac
|
|
2
|
+
class Shutdown
|
|
3
|
+
|
|
4
|
+
def initialize(connection)
|
|
5
|
+
raise "argument 'connection' must be a Connection" unless connection.is_a?(Connection)
|
|
6
|
+
@connection = connection
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
#def initiate
|
|
10
|
+
#raise unless @orchestrator.state_machine.at?(:active)
|
|
11
|
+
#@orchestrator.state_machine.to(:initiate_shutdown)
|
|
12
|
+
#nil
|
|
13
|
+
#end
|
|
14
|
+
|
|
15
|
+
#def initiated?
|
|
16
|
+
#@orchestrator.state_machine.at?([:initiate_shutdown, :shutdown, :close])
|
|
17
|
+
#end
|
|
18
|
+
|
|
19
|
+
def send_notification
|
|
20
|
+
message = Message::Exchange::ShutdownNotification.new(@connection)
|
|
21
|
+
@connection.messenger.send(message)
|
|
22
|
+
nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def receive(exchange)
|
|
26
|
+
raise MessageError unless exchange.is_a?(Message::Exchange::ShutdownNotification)
|
|
27
|
+
@connection.to(:shutdown)
|
|
28
|
+
nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class Sumac
|
|
2
|
+
class WorkerPool
|
|
3
|
+
|
|
4
|
+
def initialize(size = 1, duck_types: {})
|
|
5
|
+
raise 'Error: worker count invalid' if size < 1
|
|
6
|
+
@thread_class = duck_types[:thread] || Thread
|
|
7
|
+
@semaphore = QuackConcurrency::Semaphore.new(size)
|
|
8
|
+
@threads = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def size
|
|
12
|
+
@semaphore.permit_count
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def size=(new_size)
|
|
16
|
+
@semaphore.set_permit_count!(new_size)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run(&block)
|
|
20
|
+
@semaphore.acquire
|
|
21
|
+
@threads << @thread_class.new do
|
|
22
|
+
block.call
|
|
23
|
+
@threads.delete(@thread_class.current)
|
|
24
|
+
@semaphore.release
|
|
25
|
+
end
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def join
|
|
30
|
+
@threads.each(&:join)
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class TestIDAllocator < Test::Unit::TestCase
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def setup
|
|
5
|
+
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def teardown
|
|
10
|
+
## Nothing really
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test
|
|
15
|
+
allocator = Sumac::IDAllocator.new
|
|
16
|
+
assert_equal(allocator.allocate, 0)
|
|
17
|
+
assert_equal(allocator.allocate, 1)
|
|
18
|
+
assert_equal(allocator.allocate(5), 5)
|
|
19
|
+
#assert_not_equal(allocator.allocate(0), 0)
|
|
20
|
+
assert_equal(allocator.free(0), nil)
|
|
21
|
+
assert_equal(allocator.allocate, 0)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: sumac
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Rob Fors
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2018-02-25 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: emittable
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - '='
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.0.1
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - '='
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 0.0.1
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: quack_concurrency
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 0.0.1
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 0.0.1
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: queued_state_machine
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - '='
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: 0.0.1
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - '='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: 0.0.1
|
|
55
|
+
description: Eases implementation of computer to computer communication by enabling
|
|
56
|
+
programs to pass objects between each other.
|
|
57
|
+
email: mail@robfors.com
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- LICENSE
|
|
63
|
+
- README.md
|
|
64
|
+
- lib/core_extensions.rb
|
|
65
|
+
- lib/sumac.rb
|
|
66
|
+
- lib/sumac/adapter.rb
|
|
67
|
+
- lib/sumac/adapter/closed.rb
|
|
68
|
+
- lib/sumac/argument_error.rb
|
|
69
|
+
- lib/sumac/call_dispatcher.rb
|
|
70
|
+
- lib/sumac/call_processor.rb
|
|
71
|
+
- lib/sumac/closed_error.rb
|
|
72
|
+
- lib/sumac/closer.rb
|
|
73
|
+
- lib/sumac/connection.rb
|
|
74
|
+
- lib/sumac/exposed_object.rb
|
|
75
|
+
- lib/sumac/exposed_object_child.rb
|
|
76
|
+
- lib/sumac/forgoten.rb
|
|
77
|
+
- lib/sumac/handshake.rb
|
|
78
|
+
- lib/sumac/id_allocator.rb
|
|
79
|
+
- lib/sumac/local_reference.rb
|
|
80
|
+
- lib/sumac/local_references.rb
|
|
81
|
+
- lib/sumac/message.rb
|
|
82
|
+
- lib/sumac/message/exchange.rb
|
|
83
|
+
- lib/sumac/message/exchange/base.rb
|
|
84
|
+
- lib/sumac/message/exchange/call_request.rb
|
|
85
|
+
- lib/sumac/message/exchange/call_response.rb
|
|
86
|
+
- lib/sumac/message/exchange/compatibility_notification.rb
|
|
87
|
+
- lib/sumac/message/exchange/forget_notification.rb
|
|
88
|
+
- lib/sumac/message/exchange/id.rb
|
|
89
|
+
- lib/sumac/message/exchange/initialization_notification.rb
|
|
90
|
+
- lib/sumac/message/exchange/notification.rb
|
|
91
|
+
- lib/sumac/message/exchange/shutdown_notification.rb
|
|
92
|
+
- lib/sumac/message/object.rb
|
|
93
|
+
- lib/sumac/message/object/array.rb
|
|
94
|
+
- lib/sumac/message/object/base.rb
|
|
95
|
+
- lib/sumac/message/object/boolean.rb
|
|
96
|
+
- lib/sumac/message/object/exception.rb
|
|
97
|
+
- lib/sumac/message/object/exposed.rb
|
|
98
|
+
- lib/sumac/message/object/exposed_child.rb
|
|
99
|
+
- lib/sumac/message/object/float.rb
|
|
100
|
+
- lib/sumac/message/object/hash_table.rb
|
|
101
|
+
- lib/sumac/message/object/integer.rb
|
|
102
|
+
- lib/sumac/message/object/native_exception.rb
|
|
103
|
+
- lib/sumac/message/object/null.rb
|
|
104
|
+
- lib/sumac/message/object/string.rb
|
|
105
|
+
- lib/sumac/message_error.rb
|
|
106
|
+
- lib/sumac/messenger.rb
|
|
107
|
+
- lib/sumac/native_error.rb
|
|
108
|
+
- lib/sumac/no_method_error.rb
|
|
109
|
+
- lib/sumac/reference.rb
|
|
110
|
+
- lib/sumac/remote_entry.rb
|
|
111
|
+
- lib/sumac/remote_object.rb
|
|
112
|
+
- lib/sumac/remote_object_child.rb
|
|
113
|
+
- lib/sumac/remote_reference.rb
|
|
114
|
+
- lib/sumac/remote_references.rb
|
|
115
|
+
- lib/sumac/scheduler.rb
|
|
116
|
+
- lib/sumac/shutdown.rb
|
|
117
|
+
- lib/sumac/stale_object_error.rb
|
|
118
|
+
- lib/sumac/unexposable_object_error.rb
|
|
119
|
+
- lib/sumac/worker_pool.rb
|
|
120
|
+
- test/test_id_allocator.rb
|
|
121
|
+
homepage: https://github.com/robfors/ruby-sumac
|
|
122
|
+
licenses:
|
|
123
|
+
- Apache-2.0
|
|
124
|
+
metadata: {}
|
|
125
|
+
post_install_message:
|
|
126
|
+
rdoc_options: []
|
|
127
|
+
require_paths:
|
|
128
|
+
- lib
|
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
|
+
requirements:
|
|
131
|
+
- - ">="
|
|
132
|
+
- !ruby/object:Gem::Version
|
|
133
|
+
version: '0'
|
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
requirements: []
|
|
140
|
+
rubyforge_project:
|
|
141
|
+
rubygems_version: 2.4.8
|
|
142
|
+
signing_key:
|
|
143
|
+
specification_version: 4
|
|
144
|
+
summary: Object based communication protocol.
|
|
145
|
+
test_files: []
|