rexec 1.2.6 → 1.3.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.
@@ -4,8 +4,61 @@
4
4
  # This class is as small and independant as possible as it will get sent to clients for execution.
5
5
 
6
6
  require 'thread'
7
+ require 'monitor'
7
8
 
8
9
  module RExec
10
+
11
+ # A wrapper for sending method invocations over a Connection
12
+ class Invocation
13
+ def initialize(name, arguments)
14
+ @name = name
15
+ @arguments = arguments
16
+ end
17
+
18
+ def apply(object)
19
+ object.send(@name, *@arguments)
20
+ end
21
+
22
+ class Result
23
+ def initialize(value)
24
+ @value = value
25
+ end
26
+
27
+ attr :value
28
+ end
29
+ end
30
+
31
+ # A proxy class to create and send Invocation objects via a Connection, and receive a result.
32
+ class Proxy
33
+ def initialize(connection)
34
+ @connection = connection
35
+
36
+ @method_mutex = Mutex.new
37
+ end
38
+
39
+ def method_missing(name, *arguments)
40
+ invocation = Invocation.new(name, arguments)
41
+ result = nil
42
+
43
+ # Connection provides no transaction support. This means that
44
+ # if multiple threads are sending and receiving arbirary objects
45
+ # via the connection, the Proxy object may fail due to out of
46
+ # line objects.
47
+ @method_mutex.synchronize do
48
+ # Send the invocation.
49
+ @connection.send_object(invocation)
50
+
51
+ # Wait for the result.
52
+ result = @connection.receive_object
53
+ end
54
+
55
+ if Invocation::Result === result
56
+ return result.value
57
+ else
58
+ raise InvalidResponse.new("Invalid response received: #{result}")
59
+ end
60
+ end
61
+ end
9
62
 
10
63
  # This class represents an abstract connection to another ruby process. The interface does not impose
11
64
  # any structure on the way this communication link works, except for the fact you can send and receive
@@ -44,8 +97,17 @@ module RExec
44
97
 
45
98
  @receive_mutex = Mutex.new
46
99
  @send_mutex = Mutex.new
100
+
101
+ @proxy = Proxy.new(self)
102
+ @handler = nil
47
103
  end
48
104
 
105
+ # The object that will handle remote proxy invocations.
106
+ attr :handler, true
107
+
108
+ # The proxy object that will dispatch RPCs.
109
+ attr :proxy
110
+
49
111
  # The pipe used for reading data
50
112
  def input
51
113
  @input
@@ -89,7 +151,12 @@ module RExec
89
151
  end
90
152
 
91
153
  begin
92
- yield object
154
+ if @handler && Invocation === object
155
+ result = object.apply(@handler)
156
+ send_object(Invocation::Result.new(result))
157
+ else
158
+ yield object
159
+ end
93
160
  rescue Exception => ex
94
161
  send_object(ex)
95
162
  end
@@ -21,8 +21,8 @@
21
21
  module RExec
22
22
  module VERSION
23
23
  MAJOR = 1
24
- MINOR = 2
25
- TINY = 6
24
+ MINOR = 3
25
+ TINY = 0
26
26
 
27
27
  STRING = [MAJOR, MINOR, TINY].join('.')
28
28
  end
@@ -18,6 +18,14 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
+ module RemoteProxy
22
+ def self.foo
23
+ return :bar
24
+ end
25
+ end
26
+
27
+ $connection.handler = RemoteProxy
28
+
21
29
  $connection.run do |object|
22
30
  case(object[0])
23
31
  when :bounce
@@ -39,30 +39,43 @@ end
39
39
  BOUNCE = "Apples and Oranges"
40
40
 
41
41
  class RemoteServerTest < Test::Unit::TestCase
42
- def test_block_execution
43
- code = Pathname.new(__FILE__).dirname + "./client.rb"
44
-
45
- RExec::start_server(code.read, COMMAND) do |conn, pid|
46
- conn.send_object([:bounce, BOUNCE])
47
-
48
- assert_equal BOUNCE, conn.receive_object
49
-
50
- conn.dump_errors
51
-
52
- conn.stop
53
- end
54
- end
55
-
56
- def test_result_execution
57
- code = Pathname.new(__FILE__).dirname + "./client.rb"
58
-
59
- conn, pid = RExec::start_server(code.read, COMMAND, :passthrough => [])
60
-
61
- conn.send_object([:bounce, BOUNCE])
62
- assert_equal BOUNCE, conn.receive_object
63
-
64
- conn.dump_errors
65
-
66
- conn.stop
67
- end
42
+ def test_block_execution
43
+ code = Pathname.new(__FILE__).dirname + "./client.rb"
44
+
45
+ RExec::start_server(code.read, COMMAND) do |conn, pid|
46
+ conn.send_object([:bounce, BOUNCE])
47
+
48
+ assert_equal BOUNCE, conn.receive_object
49
+
50
+ conn.dump_errors
51
+
52
+ conn.stop
53
+ end
54
+ end
55
+
56
+ def test_result_execution
57
+ code = Pathname.new(__FILE__).dirname + "./client.rb"
58
+
59
+ conn, pid = RExec::start_server(code.read, COMMAND)
60
+
61
+ conn.send_object([:bounce, BOUNCE])
62
+ assert_equal BOUNCE, conn.receive_object
63
+
64
+ conn.dump_errors
65
+
66
+ conn.stop
67
+ end
68
+
69
+ def test_proxy
70
+ code = Pathname.new(__FILE__).dirname + "./client.rb"
71
+
72
+ conn, pid = RExec::start_server(code.read, COMMAND)
73
+
74
+ assert_equal conn.proxy.foo, :bar
75
+
76
+ conn.dump_errors
77
+
78
+ conn.stop
79
+ end
68
80
  end
81
+
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 2
8
- - 6
9
- version: 1.2.6
7
+ - 3
8
+ - 0
9
+ version: 1.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Samuel Williams
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-07-17 00:00:00 +12:00
17
+ date: 2011-07-31 00:00:00 +12:00
18
18
  default_executable: daemon-exec
19
19
  dependencies: []
20
20