rexec 1.3.0 → 1.4.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.
- 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.
|