rexec 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rexec.rb +0 -1
- data/lib/rexec/connection.rb +2 -62
- data/lib/rexec/server.rb +14 -9
- data/lib/rexec/version.rb +1 -1
- data/test/client.rb +0 -8
- data/test/remote_server_test.rb +2 -14
- metadata +10 -7
data/lib/rexec.rb
CHANGED
data/lib/rexec/connection.rb
CHANGED
@@ -1,64 +1,12 @@
|
|
1
1
|
# Copyright (c) 2007, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
|
2
2
|
# Released under the MIT license. Please see LICENSE.txt for license details.
|
3
3
|
|
4
|
-
# This
|
4
|
+
# This code is as small and independant as possible as it will get sent to clients for execution.
|
5
5
|
|
6
6
|
require 'thread'
|
7
7
|
require 'monitor'
|
8
8
|
|
9
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
|
62
10
|
|
63
11
|
# This class represents an abstract connection to another ruby process. The interface does not impose
|
64
12
|
# any structure on the way this communication link works, except for the fact you can send and receive
|
@@ -97,9 +45,6 @@ module RExec
|
|
97
45
|
|
98
46
|
@receive_mutex = Mutex.new
|
99
47
|
@send_mutex = Mutex.new
|
100
|
-
|
101
|
-
@proxy = Proxy.new(self)
|
102
|
-
@handler = nil
|
103
48
|
end
|
104
49
|
|
105
50
|
# The object that will handle remote proxy invocations.
|
@@ -151,12 +96,7 @@ module RExec
|
|
151
96
|
end
|
152
97
|
|
153
98
|
begin
|
154
|
-
|
155
|
-
result = object.apply(@handler)
|
156
|
-
send_object(Invocation::Result.new(result))
|
157
|
-
else
|
158
|
-
yield object
|
159
|
-
end
|
99
|
+
yield object
|
160
100
|
rescue Exception => ex
|
161
101
|
send_object(ex)
|
162
102
|
end
|
data/lib/rexec/server.rb
CHANGED
@@ -72,24 +72,29 @@ module RExec
|
|
72
72
|
options[:passthrough] = :err unless options[:passthrough]
|
73
73
|
|
74
74
|
send_code = Proc.new do |cin|
|
75
|
-
|
76
|
-
|
75
|
+
unless options[:raw]
|
76
|
+
cin.puts(CONNECTION_CODE)
|
77
|
+
cin.puts(CLIENT_CODE)
|
78
|
+
end
|
79
|
+
|
77
80
|
cin.puts(code)
|
78
81
|
end
|
79
82
|
|
80
83
|
if block_given?
|
81
|
-
Task.open(command, options) do |
|
82
|
-
conn = Connection.build(
|
84
|
+
Task.open(command, options) do |task|
|
85
|
+
conn = Connection.build(task, options, &send_code)
|
86
|
+
|
87
|
+
yield conn, task
|
83
88
|
|
84
|
-
yield conn, process.pid
|
85
|
-
|
86
89
|
conn.stop
|
90
|
+
task.stop
|
91
|
+
task.wait
|
87
92
|
end
|
88
93
|
else
|
89
|
-
|
90
|
-
conn = Connection.build(
|
94
|
+
task = Task.open(command, options)
|
95
|
+
conn = Connection.build(task, options, &send_code)
|
91
96
|
|
92
|
-
return conn,
|
97
|
+
return conn, task
|
93
98
|
end
|
94
99
|
end
|
95
100
|
end
|
data/lib/rexec/version.rb
CHANGED
data/test/client.rb
CHANGED
@@ -18,14 +18,6 @@
|
|
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
|
-
|
29
21
|
$connection.run do |object|
|
30
22
|
case(object[0])
|
31
23
|
when :bounce
|
data/test/remote_server_test.rb
CHANGED
@@ -42,7 +42,7 @@ class RemoteServerTest < Test::Unit::TestCase
|
|
42
42
|
def test_block_execution
|
43
43
|
code = Pathname.new(__FILE__).dirname + "./client.rb"
|
44
44
|
|
45
|
-
RExec::start_server(code.read, COMMAND) do |conn,
|
45
|
+
RExec::start_server(code.read, COMMAND) do |conn, task|
|
46
46
|
conn.send_object([:bounce, BOUNCE])
|
47
47
|
|
48
48
|
assert_equal BOUNCE, conn.receive_object
|
@@ -56,7 +56,7 @@ class RemoteServerTest < Test::Unit::TestCase
|
|
56
56
|
def test_result_execution
|
57
57
|
code = Pathname.new(__FILE__).dirname + "./client.rb"
|
58
58
|
|
59
|
-
conn,
|
59
|
+
conn, task = RExec::start_server(code.read, COMMAND)
|
60
60
|
|
61
61
|
conn.send_object([:bounce, BOUNCE])
|
62
62
|
assert_equal BOUNCE, conn.receive_object
|
@@ -65,17 +65,5 @@ class RemoteServerTest < Test::Unit::TestCase
|
|
65
65
|
|
66
66
|
conn.stop
|
67
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
|
80
68
|
end
|
81
69
|
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rexec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 7
|
5
|
+
prerelease:
|
5
6
|
segments:
|
6
7
|
- 1
|
7
|
-
-
|
8
|
+
- 4
|
8
9
|
- 0
|
9
|
-
version: 1.
|
10
|
+
version: 1.4.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Samuel Williams
|
@@ -14,8 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2011-
|
18
|
-
default_executable: daemon-exec
|
18
|
+
date: 2011-08-08 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description:
|
@@ -51,7 +51,6 @@ files:
|
|
51
51
|
- test/task.rb
|
52
52
|
- test/task_test.rb
|
53
53
|
- README.md
|
54
|
-
has_rdoc: yard
|
55
54
|
homepage: http://www.oriontransfer.co.nz/gems/rexec
|
56
55
|
licenses: []
|
57
56
|
|
@@ -61,23 +60,27 @@ rdoc_options: []
|
|
61
60
|
require_paths:
|
62
61
|
- lib
|
63
62
|
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
64
|
requirements:
|
65
65
|
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
+
hash: 3
|
67
68
|
segments:
|
68
69
|
- 0
|
69
70
|
version: "0"
|
70
71
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
71
73
|
requirements:
|
72
74
|
- - ">="
|
73
75
|
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
74
77
|
segments:
|
75
78
|
- 0
|
76
79
|
version: "0"
|
77
80
|
requirements: []
|
78
81
|
|
79
82
|
rubyforge_project:
|
80
|
-
rubygems_version: 1.
|
83
|
+
rubygems_version: 1.8.7
|
81
84
|
signing_key:
|
82
85
|
specification_version: 3
|
83
86
|
summary: RExec (Remote Execution) is a tool to facilitate communicating to another ruby process and executing code.
|