async-bus 0.1.0 → 0.1.1

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: 354c43b3ef6922366c369eb209cede56b7bbca16d896b718ebfbe222eb7a4d97
4
- data.tar.gz: 856c7c3cd32189b912d3115a3c218a1210215d4850391b18b7d0960be0686de9
3
+ metadata.gz: f0862030bd7ad9cf8ffe84a3e35e4ec52e3c3f3cc81b8192c5d59cc0bc435e3c
4
+ data.tar.gz: d2f9a0398f4aa94a35fc3d2dc8aa1d4097777e9f85eeab2ca19405e30d902aa5
5
5
  SHA512:
6
- metadata.gz: a38c42252effdbadbacd1d15da7d1e76f2632085430e3954668d0cef74b18404462b3c51ed6303598510679707c75d0bdbce7b1cc622a1abd2d70d126e5d457b
7
- data.tar.gz: da3e7ccca7be7eb09180aa85d62412393056c36a38aee64b418feaef02dd244367f636c7d6a4bbb4a2a88b3aa993b7ab8447885c2c14b8dda25a47f13725c713
6
+ metadata.gz: f4f6d79a2da0ecd4cba25ad79a2be878728701c01113c6f65aa6f9980a863a721f8863841bcfb1c0206f21e25bd0d1b4747a97102b3fbc2b5658dd045c1bf58d
7
+ data.tar.gz: ecc5632d806ceebbf5b61aebc85ae1b47118303cf9f03320ecc243b403ca7edb00cf60ee966a55cc7c247bd4969897ef10588a97940c55518603fd34afb7c6fc
@@ -54,8 +54,13 @@ module Async
54
54
  @id = id
55
55
 
56
56
  @objects = {}
57
+ @proxies = ::ObjectSpace::WeakMap.new
58
+ @finalized = Thread::Queue.new
57
59
  end
58
60
 
61
+ attr :objects
62
+ attr :proxies
63
+
59
64
  attr :unpacker
60
65
  attr :packer
61
66
 
@@ -69,7 +74,7 @@ module Async
69
74
  attr :transactions
70
75
 
71
76
  def proxy(object)
72
- name = "proxy:#{object_id}"
77
+ name = next_id.to_s(16).freeze
73
78
 
74
79
  bind(name, object)
75
80
 
@@ -80,11 +85,23 @@ module Async
80
85
  @objects[name] = object
81
86
  end
82
87
 
88
+ private def finalize(name)
89
+ proc{@finalized << name}
90
+ end
91
+
83
92
  def [](name)
84
- Proxy.new(self, name)
93
+ unless proxy = @proxies[name]
94
+ proxy = Proxy.new(self, name)
95
+ @proxies[name] = proxy
96
+
97
+ ObjectSpace.define_finalizer(proxy, finalize(name))
98
+ end
99
+
100
+ return proxy
85
101
  end
86
102
 
87
- def invoke(name, arguments, options, &block)
103
+ def invoke(name, arguments, options = {}, &block)
104
+
88
105
  id = self.next_id
89
106
 
90
107
  transaction = Transaction.new(self, id)
@@ -94,11 +111,19 @@ module Async
94
111
  end
95
112
 
96
113
  def run
97
- # @unpacker.each do |message|
114
+ finalizer_task = Async do
115
+ while name = @finalized.pop
116
+ @packer.write([:release, name])
117
+ end
118
+ end
119
+
98
120
  @unpacker.each do |message|
99
121
  id = message.shift
100
122
 
101
- if transaction = @transactions[id]
123
+ if id == :release
124
+ name = message.shift
125
+ @objects.delete(name) if name.is_a?(String)
126
+ elsif transaction = @transactions[id]
102
127
  transaction.received.enqueue(message)
103
128
  elsif message.first == :invoke
104
129
  message.shift
@@ -119,11 +144,14 @@ module Async
119
144
  end
120
145
  end
121
146
  ensure
147
+ finalizer_task.stop
148
+
122
149
  @transactions.each do |id, transaction|
123
150
  transaction.close
124
151
  end
125
152
 
126
153
  @transactions.clear
154
+ @proxies = ::ObjectSpace::WeakMap.new
127
155
  end
128
156
 
129
157
  def close
@@ -22,21 +22,53 @@ module Async
22
22
  module Bus
23
23
  module Protocol
24
24
  class Proxy < BasicObject
25
- def initialize(bus, name)
26
- @bus = bus
25
+ def initialize(connection, name)
26
+ @connection = connection
27
27
  @name = name
28
28
  end
29
29
 
30
+ def !
31
+ @connection.invoke(@name, [:!])
32
+ end
33
+
34
+ def == object
35
+ @connection.invoke(@name, [:==, object])
36
+ end
37
+
38
+ def != object
39
+ @connection.invoke(@name, [:!=, object])
40
+ end
41
+
42
+ def eql?(other)
43
+ self.equal?(other)
44
+ end
45
+
46
+ def methods(all = true)
47
+ @connection.invoke(@name, [:methods, all]) | super
48
+ end
49
+
50
+ def protected_methods(all = true)
51
+ @connection.invoke(@name, [:protected_methods, all]) | super
52
+ end
53
+
54
+ def public_methods(all = true)
55
+ @connection.invoke(@name, [:public_methods, all]) | super
56
+ end
57
+
30
58
  def inspect
31
- "[Proxy #{method_missing(:inspect)}]"
59
+ "[Proxy (#{@name}) #{method_missing(:inspect)}]"
32
60
  end
33
61
 
34
62
  def method_missing(*arguments, **options, &block)
35
- @bus.invoke(@name, arguments, options, &block)
63
+ @connection.invoke(@name, arguments, options, &block)
36
64
  end
37
65
 
38
66
  def respond_to?(name, include_all = false)
39
- @bus.invoke(@name, [:respond_to?, name, include_all])
67
+ @connection.invoke(@name, [:respond_to?, name, include_all])
68
+ end
69
+
70
+ def respond_to_missing?(name, include_all = false)
71
+ @connection.invoke(@name, [:respond_to?, name, include_all]) || super
40
72
  end
41
73
  end
42
74
  end
@@ -61,6 +61,8 @@ module Async
61
61
 
62
62
  # Invoke a remote procedure.
63
63
  def invoke(name, arguments, options, &block)
64
+ Console.logger.debug(self) {[name, arguments, options, block]}
65
+
64
66
  self.write(:invoke, name, arguments, options, block_given?)
65
67
 
66
68
  while response = self.read
@@ -22,6 +22,6 @@
22
22
 
23
23
  module Async
24
24
  module Bus
25
- VERSION = "0.1.0"
25
+ VERSION = "0.1.1"
26
26
  end
27
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-bus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -74,12 +74,10 @@ extra_rdoc_files: []
74
74
  files:
75
75
  - lib/async/bus.rb
76
76
  - lib/async/bus/client.rb
77
- - lib/async/bus/local.rb
78
77
  - lib/async/bus/protocol/connection.rb
79
78
  - lib/async/bus/protocol/proxy.rb
80
79
  - lib/async/bus/protocol/transaction.rb
81
80
  - lib/async/bus/protocol/wrapper.rb
82
- - lib/async/bus/remote.rb
83
81
  - lib/async/bus/server.rb
84
82
  - lib/async/bus/version.rb
85
83
  homepage: https://github.com/socketry/async-bus
@@ -1,61 +0,0 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require_relative 'proxy'
22
-
23
- module Async
24
- module Bus
25
- class Local
26
- def initialize
27
- @instances = {}
28
- end
29
-
30
- def close
31
- @instances.clear
32
- end
33
-
34
- def []= name, instance
35
- @instances[name] = instance
36
-
37
- Proxy.new(self, name, instance)
38
- end
39
-
40
- def [] name
41
- Proxy.new(self, name, @instances[name])
42
- end
43
-
44
- class Proxy < Bus::Proxy
45
- def initialize(name, bus, instance)
46
- super(name, bus)
47
-
48
- @instance = instance
49
- end
50
-
51
- def method_missing(name, *args, &block)
52
- @instance.send(name, *args, &block)
53
- end
54
-
55
- def respond_to?(*args)
56
- @instance.respond_to?(*args)
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,69 +0,0 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require_relative 'proxy'
22
-
23
- module Async
24
- module Bus
25
- class Remote
26
- def initialize(connection)
27
- @connection = connection
28
- end
29
-
30
- def close
31
- @instances.clear
32
- end
33
-
34
- def []= name, instance
35
- @instances[name] = instance
36
-
37
- @connection.
38
-
39
- Proxy.new(self, name, instance)
40
- end
41
-
42
- def [] name
43
- Proxy.new(self, name, @instances[name])
44
- end
45
-
46
- def invoke(name, *arguments, **options, &block)
47
- @connection.invoke(name, arguments, options, block_given?) do |transaction|
48
- while response = transaction.read
49
- what, *arguments = response
50
-
51
- case what
52
- when :error
53
- raise(*arguments)
54
- when :return
55
- return(*arguments)
56
- when :yield
57
- begin
58
- result = yield(*arguments)
59
- transaction.write(:next, result)
60
- rescue => error
61
- transaction.write(:error, error)
62
- end
63
- end
64
- end
65
- end
66
- end
67
- end
68
- end
69
- end