easy-serve 0.4 → 0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa7e317b0835fcccb71074755f7c440a36eb97c5
4
- data.tar.gz: f1473351a5081398d0c1a8dc4fe424555cbe7a8b
3
+ metadata.gz: 969ade3d5e6c485793ca23d6ef8f7b0acb158d10
4
+ data.tar.gz: 41691d84a7c64a1d0139b2a7e2245df8828e4f19
5
5
  SHA512:
6
- metadata.gz: 3f5ee396c21115e4d691c15409aa47f07ca9947a82753e33db9663f21e58ba0930f53541a193095b9705a44d14d96018ad6c03c38a187c407379d90196c7c1ac
7
- data.tar.gz: b4027e51407e2070ec4039f70fda510cc5b8a22e5aae5396de86c360e2c2366840f9436bd84d313fc0b2ead5df016c4ff7cd4c83276d719512da868a82a64123
6
+ metadata.gz: 7d5ade10938afc5541a00fd21a4f6fd24ecae7834e2465d13cd6aac2956ae1d23ed5b3bb464f901364e56844638ce56f5c65d902e69f8c719b4f8937ac086061
7
+ data.tar.gz: 4d5896f0406a5a2d8ece78002ed7dccaaea1cfa233e685d0ed5c72d3b9434a9a8aeae0803437f56aec13d2c87e21ec0c35ee724043083f0881d40c3ce7f4814c
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
1
  easy-serve
2
2
  ==========
3
3
 
4
- Framework for starting tcp/unix servers and connected clients under one parent process.
4
+ Framework for starting tcp/unix servers and connected clients under one parent process and on remote hosts.
data/examples/multi.rb CHANGED
@@ -26,7 +26,7 @@ EasyServe.start servers_file: servers_file do |ez|
26
26
  end
27
27
  end
28
28
 
29
- ez.client "simple-server" do |conn|
29
+ ez.child "simple-server" do |conn|
30
30
  log.progname = "client with pid=#$$"
31
31
  log.info conn.read
32
32
  conn.write "hello from #{log.progname}"
data/examples/passive.rb CHANGED
@@ -21,7 +21,7 @@ EasyServe.start do |ez|
21
21
  end
22
22
  end
23
23
 
24
- ez.client "simple-server", passive: true do |conn|
24
+ ez.child "simple-server", passive: true do |conn|
25
25
  log.progname = "client 1"
26
26
  log.info conn.read
27
27
  conn.write "hello from #{log.progname}, pid = #$$; sleeping..."
@@ -31,7 +31,7 @@ EasyServe.start do |ez|
31
31
 
32
32
  sleep 0.1
33
33
 
34
- ez.client "simple-server" do |conn|
34
+ ez.child "simple-server" do |conn|
35
35
  log.progname = "client 2"
36
36
  log.info conn.read
37
37
  conn.write "hello from #{log.progname}, pid = #$$"
@@ -0,0 +1,78 @@
1
+ require 'easy-serve/remote'
2
+
3
+ addr_there = ARGV.shift
4
+
5
+ unless addr_there
6
+ abort <<-END
7
+
8
+ Usage: #$0 addr_there
9
+
10
+ The 'addr_there' is the remote address on which client code will run.
11
+ It must be a destination accepted by ssh, optionally including a user name:
12
+
13
+ [user@]hostname
14
+
15
+ The 'hostname' may by any valid hostname or ssh alias.
16
+
17
+ END
18
+ end
19
+
20
+ EasyServe.start do |ez|
21
+ log = ez.log
22
+ log.level = Logger::INFO
23
+ log.formatter = nil if $VERBOSE
24
+
25
+ ez.start_servers do
26
+ ez.server "simple-server", :tcp, nil, 0 do |svr|
27
+ Thread.new do
28
+ loop do
29
+ Thread.new(svr.accept) do |conn|
30
+ log.info "accepted connection from #{conn.inspect}"
31
+ conn.write "hello from #{log.progname}"
32
+ log.info "wrote greeting"
33
+ conn.close_write
34
+ log.info "trying to read from #{conn.inspect}"
35
+ log.info "received: #{conn.read}"
36
+ conn.close
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ ez.remote "simple-server", host: addr_there, log: true, passive: true,
44
+ eval: %{
45
+ conn = conns[0]
46
+ # this code is executed on the remote host, connected by conn, not drb
47
+ log.progname = "eval remote 1 (passive) on \#{host}"
48
+ log.info "trying to read from \#{conn.inspect}"
49
+ log.info "received: \#{conn.read}"
50
+ conn.write "hello from \#{log.progname}"
51
+ conn.close
52
+
53
+ sleep
54
+ # Without passive, this sleep would prevent the distributed app from
55
+ # exiting -- the simple-server above could not be safely stopped, since
56
+ # there's no guarantee that it is no longer needed. The passive
57
+ # declaration make it clear that this process can be stopped after all
58
+ # non-passive clients have finished, and then the server can be stopped.
59
+ # Of course, this also means that if all other clients execute very
60
+ # quickly, this client might never get a chance to run.
61
+ }
62
+
63
+ sleep 1 # Ensure (for testing) that the above client runs.
64
+
65
+ ez.remote "simple-server", host: addr_there, log: true, eval: %{
66
+ conn = conns[0]
67
+ # this code is executed on the remote host, connected by conn, not drb
68
+ log.progname = "eval remote 2 on \#{host}"
69
+ log.info "trying to read from \#{conn.inspect}"
70
+ log.info "received: \#{conn.read}"
71
+ conn.write "hello from \#{log.progname}"
72
+ conn.close
73
+ }
74
+ # Note use of \#{} to interpolate variables that are only available
75
+ # in the binding where the code is eval-ed. Alternately, use
76
+ # eval: %Q{...}
77
+ # but then interpolation from this script is not posssible.
78
+ end
@@ -40,7 +40,7 @@ EasyServe.start do |ez|
40
40
  end
41
41
  end
42
42
 
43
- ez.remote "simple-server", host: addr_there, eval: %{
43
+ ez.remote "simple-server", host: addr_there, log: true, eval: %{
44
44
  conn = conns[0]
45
45
  # this code is executed on the remote host, connected by conn, not drb
46
46
  log.progname = "eval remote on \#{host}"
@@ -10,7 +10,7 @@ class RemoteRunScript
10
10
 
11
11
  def run
12
12
  conn = conns[0]
13
- log.progname = "run remote on #{host}"
13
+ log.progname = "run remote on #{host} with args #{args}"
14
14
  log.info "trying to read from #{conn.inspect}"
15
15
  log.info "received: #{conn.read}"
16
16
  conn.write "hello from #{log.progname}"
@@ -49,5 +49,9 @@ EasyServe.start do |ez|
49
49
  file: "remote-run-script.rb",
50
50
  # 'file' passed to load, so can be rel to dir or ruby's $LOAD_PATH
51
51
  class_name: "RemoteRunScript",
52
- args: []
52
+ args: ["foo", "bar", 1, 2, 3],
53
+ log: true # use the default logger, sending log messages back to local
54
+ #log: false # don't log
55
+ #log: ["remote-run.log", "weekly"]
56
+ # log to a remote file with rotation (like Logger.new(...) )
53
57
  end
data/examples/simple.rb CHANGED
@@ -20,7 +20,7 @@ EasyServe.start do |ez|
20
20
  end
21
21
  end
22
22
 
23
- ez.client "simple-server" do |conn|
23
+ ez.child "simple-server" do |conn|
24
24
  log.progname = "client 1"
25
25
  log.info conn.read
26
26
  conn.write "hello from #{log.progname}"
data/lib/easy-serve.rb CHANGED
@@ -4,7 +4,7 @@ require 'yaml'
4
4
  require 'fileutils'
5
5
 
6
6
  class EasyServe
7
- VERSION = "0.4"
7
+ VERSION = "0.5"
8
8
 
9
9
  class Server
10
10
  attr_reader :name, :pid, :addr
@@ -36,8 +36,8 @@ class EasyServe
36
36
 
37
37
  attr_accessor :log
38
38
  attr_accessor :servers
39
- attr_reader :clients
40
- attr_reader :passive_clients
39
+ attr_reader :children
40
+ attr_reader :passive_children
41
41
  attr_reader :servers_file
42
42
  attr_reader :interactive
43
43
 
@@ -55,9 +55,10 @@ class EasyServe
55
55
  @servers_file = opts[:servers_file]
56
56
  @interactive = opts[:interactive]
57
57
  @log = opts[:log] || self.class.null_logger
58
- @clients = [] # pid
59
- @passive_clients = [] # pid
58
+ @children = [] # pid
59
+ @passive_children = [] # pid
60
60
  @owner = false
61
+ @tmpdir = nil
61
62
  @servers = opts[:servers] # name => Server
62
63
 
63
64
  unless servers
@@ -92,7 +93,7 @@ class EasyServe
92
93
  trap("INT", handler)
93
94
  end
94
95
 
95
- clients.each do |pid|
96
+ children.each do |pid|
96
97
  log.debug {"waiting for client pid=#{pid} to stop"}
97
98
  begin
98
99
  Process.waitpid pid
@@ -101,7 +102,7 @@ class EasyServe
101
102
  end
102
103
  end
103
104
 
104
- passive_clients.each do |pid|
105
+ passive_children.each do |pid|
105
106
  log.debug {"stopping client pid=#{pid}"}
106
107
  Process.kill("TERM", pid)
107
108
  begin
@@ -251,20 +252,29 @@ class EasyServe
251
252
  raise ArgumentError, "unknown server_class: #{server_class.inspect}"
252
253
  end
253
254
  raise
255
+
256
+ rescue => ex
257
+ ex.message << "; addr=#{server_addr.inspect}"
258
+ raise
254
259
  end
255
260
  end
256
261
 
257
- # A passive client may be stopped after all active clients exit.
258
- def client *server_names, passive: false
262
+ # A passive client child may be stopped after all active clients exit.
263
+ def child *server_names, passive: false
259
264
  c = fork do
260
265
  conns = server_names.map {|sn| socket_for(*servers[sn].addr)}
261
266
  yield(*conns) if block_given?
262
267
  no_interrupt_if_interactive
263
268
  end
264
- (passive ? passive_clients : clients) << c
269
+ (passive ? passive_children : children) << c
265
270
  c
266
271
  end
267
272
 
273
+ def client *args, &block
274
+ warn "EasyServe#client is deprecated; use #child"
275
+ child *args, &block
276
+ end
277
+
268
278
  def local *server_names
269
279
  conns = server_names.map {|sn| socket_for(*servers[sn].addr)}
270
280
  yield(*conns) if block_given?
@@ -283,7 +293,7 @@ class EasyServe
283
293
  end
284
294
  socket_class.new(*addr)
285
295
  rescue => ex
286
- ex.message << " addr=#{addr.inspect}"
296
+ ex.message << "; addr=#{addr.inspect}"
287
297
  raise
288
298
  end
289
299
 
@@ -1,9 +1,12 @@
1
1
  require 'drb'
2
2
 
3
3
  class EasyServe
4
- # useful for testing only -- use _eval or _run for production
4
+ # useful for testing only -- use _eval or _run for production.
5
+ # Note: as with #local, the code block runs in the main thread, by default.
6
+ # It's up to you to start another thread inside the code block if you
7
+ # want more concurrency. This is for convenience when testing (cases in which
8
+ # concurrency needs to be controlled explicitly).
5
9
  def remote_drb *server_names, host: nil
6
- ## passive option?
7
10
  ## remote logfile option?
8
11
 
9
12
  DRb.start_service("druby://#{host_name}:0", nil)
@@ -0,0 +1,66 @@
1
+ require 'msgpack'
2
+ require 'easy-serve'
3
+
4
+ def manage_remote_eval_client msg
5
+ $VERBOSE = msg["verbose"]
6
+ server_names, servers_list, log_level, eval_string, host =
7
+ msg.values_at(*%w{server_names servers_list log_level eval_string host})
8
+
9
+ servers = {}
10
+ servers_list.each do |name, pid, addr|
11
+ servers[name] = EasyServe::Server.new(name, pid, addr)
12
+ end
13
+
14
+ log_args = msg["log"]
15
+ log =
16
+ case log_args
17
+ when Array
18
+ Logger.new(*log_args)
19
+ when true
20
+ EasyServe.default_logger
21
+ when nil, false
22
+ EasyServe.null_logger
23
+ end
24
+
25
+ EasyServe.start servers: servers, log: log do |ez|
26
+ log = ez.log
27
+ log.level = log_level
28
+ log.formatter = nil if $VERBOSE
29
+
30
+ ez.local *server_names do |*conns|
31
+ begin
32
+ pr = eval "proc do |conns, host, log| #{eval_string}; end"
33
+ pr[conns, host, log]
34
+ rescue => ex
35
+ puts "ez error", ex, ex.backtrace
36
+ end
37
+ end
38
+
39
+ log.info "done"
40
+ end
41
+ rescue => ex
42
+ puts "ez error", ex, ex.backtrace
43
+ end
44
+
45
+ $stdout.sync = true
46
+
47
+ def handle_remote_eval_messages
48
+ unpacker = MessagePack::Unpacker.new($stdin)
49
+ unpacker.each do |msg|
50
+ case
51
+ when msg["server_names"]
52
+ Thread.new {manage_remote_eval_client(msg); exit}
53
+ when msg["exit"]
54
+ puts "exiting"
55
+ exit
56
+ when msg["request"]
57
+ response = self.send(*msg["command"])
58
+ puts "response: #{response.inspect}"
59
+ else
60
+ puts "unhandled: #{msg.inspect}"
61
+ end
62
+ end
63
+
64
+ rescue => ex
65
+ puts "ez error", ex, ex.backtrace
66
+ end
@@ -1,63 +1,54 @@
1
+ require 'msgpack'
2
+
1
3
  class EasyServe
2
4
  # useful simple cases in testing and in production, but long eval strings
3
- # can be hard to debug -- use _run instead
4
- def remote_eval *server_names, host: nil, **opts
5
- ## passive option?
6
- ## remote logfile option?
5
+ # can be hard to debug -- use _run instead. Returns pid of child managing
6
+ # the ssh connection.
7
+ #
8
+ # Note, unlike #local and #child, by default logging goes to the null logger.
9
+ # If you want too see logs from the remote, you need to choose:
10
+ #
11
+ # 1. Log to remote file: pass log: [args...] with args as in Logger.new
12
+ #
13
+ # 2. Log back over ssh: pass log: true.
14
+ #
15
+ def remote_eval *server_names, host: nil, passive: false, **opts
16
+ child_pid = fork do
17
+ log.progname = "remote_eval #{host}"
7
18
 
8
- log.progname = "remote_eval #{host}"
19
+ IO.popen [
20
+ "ssh", host, "ruby",
21
+ "-r", "easy-serve/remote-eval-mgr",
22
+ "-e", "handle_remote_eval_messages"],
23
+ "w+" do |ssh|
24
+ ssh.sync = true
9
25
 
10
- IO.popen ["ssh", host, "ruby"], "w+" do |ssh|
11
- ssh.puts %Q{
12
- $stdout.sync = true
13
- begin
14
- require 'yaml'
15
- require 'easy-serve'
16
-
17
- class EasyServe
18
- def binding_for_remote_eval conns, host, log
19
- binding
20
- end
21
- end
22
-
23
- server_names = #{server_names.inspect}
24
- servers = YAML.load(#{YAML.dump(servers).inspect})
25
- log_level = #{log.level}
26
- eval_string = #{opts[:eval].inspect}
27
- host = #{host.inspect}
28
-
29
- EasyServe.start servers: servers do |ez|
30
- log = ez.log
31
- log.level = log_level
32
- log.formatter = nil if $VERBOSE
26
+ servers_list = servers.map {|n, s| [s.name, s.pid, s.addr]}
33
27
 
34
- ez.local *server_names do |*conns|
35
- begin
36
- eval eval_string, ez.binding_for_remote_eval(conns, host, log)
37
- rescue => ex
38
- puts "ez error", ex, ex.backtrace
39
- end
40
- end
41
- end
42
- rescue => ex
43
- puts "ez error", ex, ex.backtrace
44
- end
45
- }
46
-
47
- ssh.close_write
48
- result = ssh.gets
49
-
50
- if result
51
- error = result[/ez error/]
52
- if error
53
- raise RemoteError, "error raised in remote: #{ssh.read}"
54
- else
55
- puts result
56
- while s = ssh.gets
28
+ MessagePack.pack(
29
+ {
30
+ verbose: $VERBOSE,
31
+ server_names: server_names,
32
+ servers_list: servers_list,
33
+ log_level: log.level,
34
+ eval_string: opts[:eval],
35
+ host: host,
36
+ log: opts[:log]
37
+ },
38
+ ssh)
39
+
40
+ while s = ssh.gets
41
+ case s
42
+ when /^ez error/
43
+ raise RemoteError, "error raised in remote: #{ssh.read}"
44
+ else
57
45
  puts s
58
46
  end
59
47
  end
60
48
  end
61
49
  end
50
+
51
+ (passive ? passive_children : children) << child_pid
52
+ child_pid
62
53
  end
63
54
  end
@@ -0,0 +1,73 @@
1
+ require 'msgpack'
2
+ require 'easy-serve'
3
+
4
+ def manage_remote_run_client msg
5
+ $VERBOSE = msg["verbose"]
6
+ server_names, servers_list, log_level, host, dir, file, class_name, args =
7
+ msg.values_at(*%w{
8
+ server_names servers_list log_level host
9
+ dir file class_name args
10
+ })
11
+
12
+ servers = {}
13
+ servers_list.each do |name, pid, addr|
14
+ servers[name] = EasyServe::Server.new(name, pid, addr)
15
+ end
16
+
17
+ Dir.chdir(dir) if dir
18
+ load file
19
+
20
+ log_args = msg["log"]
21
+ log =
22
+ case log_args
23
+ when Array
24
+ Logger.new(*log_args)
25
+ when true, :default
26
+ EasyServe.default_logger
27
+ when nil, false
28
+ EasyServe.null_logger
29
+ end
30
+
31
+ EasyServe.start servers: servers, log: log do |ez|
32
+ log = ez.log
33
+ log.level = log_level
34
+ log.formatter = nil if $VERBOSE
35
+
36
+ ez.local *server_names do |*conns|
37
+ begin
38
+ cl = Object.const_get(class_name)
39
+ ro = cl.new(conns, host, log, *args)
40
+ ro.run
41
+ rescue => ex
42
+ puts "ez error", ex, ex.backtrace
43
+ end
44
+ end
45
+
46
+ log.info "done"
47
+ end
48
+ rescue => ex
49
+ puts "ez error", ex, ex.backtrace
50
+ end
51
+
52
+ $stdout.sync = true
53
+
54
+ def handle_remote_run_messages
55
+ unpacker = MessagePack::Unpacker.new($stdin)
56
+ unpacker.each do |msg|
57
+ case
58
+ when msg["server_names"]
59
+ Thread.new {manage_remote_run_client(msg); exit}
60
+ when msg["exit"]
61
+ puts "exiting"
62
+ exit
63
+ when msg["request"]
64
+ response = self.send(*msg["command"])
65
+ puts "response: #{response.inspect}"
66
+ else
67
+ puts "unhandled: #{msg.inspect}"
68
+ end
69
+ end
70
+
71
+ rescue => ex
72
+ puts "ez error", ex, ex.backtrace
73
+ end
@@ -1,61 +1,55 @@
1
+ require 'msgpack'
2
+
1
3
  class EasyServe
2
- # useful in production, though it requires remote lib files to be set up
3
- def remote_run *server_names, host: nil, **opts
4
- ## passive option?
5
- ## remote logfile option?
4
+ # useful in production, though it requires remote lib files to be set up.
5
+ # Returns pid of child managing the ssh connection.
6
+ #
7
+ # Note, unlike #local and #child, by default logging goes to the null logger.
8
+ # If you want too see logs from the remote, you need to choose:
9
+ #
10
+ # 1. Log to remote file: pass log: [args...] with args as in Logger.new
11
+ #
12
+ # 2. Log back over ssh: pass log: true.
13
+ #
14
+ def remote_run *server_names, host: nil, passive: false, **opts
15
+ child_pid = fork do
16
+ log.progname = "remote_run #{host}"
6
17
 
7
- log.progname = "remote_run #{host}"
18
+ IO.popen [
19
+ "ssh", host, "ruby",
20
+ "-r", "easy-serve/remote-run-mgr",
21
+ "-e", "handle_remote_run_messages"],
22
+ "w+" do |ssh|
23
+ ssh.sync = true
8
24
 
9
- IO.popen ["ssh", host, "ruby"], "w+" do |ssh|
10
- ssh.puts %Q{
11
- $stdout.sync = true
12
- begin
13
- require 'yaml'
14
- require 'easy-serve'
15
-
16
- server_names = #{server_names.inspect}
17
- servers = YAML.load(#{YAML.dump(servers).inspect})
18
- log_level = #{log.level}
19
- host = #{host.inspect}
20
- args = YAML.load(#{YAML.dump(opts[:args]).inspect})
21
-
22
- #{opts[:dir] && "Dir.chdir #{opts[:dir].inspect}"}
23
- load #{opts[:file].inspect}
24
-
25
- EasyServe.start servers: servers do |ez|
26
- log = ez.log
27
- log.level = log_level
28
- log.formatter = nil if $VERBOSE
25
+ servers_list = servers.map {|n, s| [s.name, s.pid, s.addr]}
26
+ MessagePack.pack(
27
+ {
28
+ verbose: $VERBOSE,
29
+ server_names: server_names,
30
+ servers_list: servers_list,
31
+ log_level: log.level,
32
+ host: host,
33
+ dir: opts[:dir],
34
+ file: opts[:file],
35
+ class_name: opts[:class_name],
36
+ args: opts[:args],
37
+ log: opts[:log]
38
+ },
39
+ ssh)
29
40
 
30
- ez.local *server_names do |*conns|
31
- begin
32
- cl = Object.const_get(#{opts[:class_name].inspect})
33
- ro = cl.new(conns, host, log, *args)
34
- ro.run
35
- rescue => ex
36
- puts "ez error", ex, ex.backtrace
37
- end
38
- end
39
- end
40
- rescue => ex
41
- puts "ez error", ex, ex.backtrace
42
- end
43
- }
44
-
45
- ssh.close_write
46
- result = ssh.gets
47
-
48
- if result
49
- error = result[/ez error/]
50
- if error
51
- raise RemoteError, "error raised in remote: #{ssh.read}"
52
- else
53
- puts result
54
- while s = ssh.gets
41
+ while s = ssh.gets
42
+ case s
43
+ when /^ez error/
44
+ raise RemoteError, "error raised in remote: #{ssh.read}"
45
+ else
55
46
  puts s
56
47
  end
57
48
  end
58
49
  end
59
50
  end
51
+
52
+ (passive ? passive_children : children) << child_pid
53
+ child_pid
60
54
  end
61
55
  end
@@ -8,15 +8,15 @@ class EasyServe
8
8
 
9
9
  if opts[:eval]
10
10
  require 'easy-serve/remote-eval'
11
- remote_eval *server_names, host: host, **opts
11
+ remote_eval(*server_names, host: host, **opts)
12
12
 
13
13
  elsif opts[:file]
14
14
  require 'easy-serve/remote-run'
15
- remote_run *server_names, host: host, **opts
15
+ remote_run(*server_names, host: host, **opts)
16
16
 
17
17
  elsif block_given?
18
18
  require 'easy-serve/remote-drb'
19
- remote_drb *server_names, host: host, **opts, &Proc.new
19
+ remote_drb(*server_names, host: host, **opts, &Proc.new)
20
20
 
21
21
  else
22
22
  raise ArgumentError, "cannot select remote mode based on arguments"
metadata CHANGED
@@ -1,17 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy-serve
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.4'
4
+ version: '0.5'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel VanderWerf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-26 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2013-08-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: msgpack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description: Framework for starting tcp/unix servers and connected clients under one
14
- parent process.
28
+ parent process and on remote hosts.
15
29
  email: vjoel@users.sourceforge.net
16
30
  executables: []
17
31
  extensions: []
@@ -22,13 +36,16 @@ files:
22
36
  - README.md
23
37
  - COPYING
24
38
  - lib/easy-serve.rb
39
+ - lib/easy-serve/remote-eval-mgr.rb
25
40
  - lib/easy-serve/remote-run.rb
26
41
  - lib/easy-serve/remote-drb.rb
27
42
  - lib/easy-serve/remote.rb
28
43
  - lib/easy-serve/remote-eval.rb
44
+ - lib/easy-serve/remote-run-mgr.rb
29
45
  - examples/simple.rb
30
46
  - examples/remote-manual.rb
31
47
  - examples/multi.rb
48
+ - examples/remote-eval-passive.rb
32
49
  - examples/remote-run.rb
33
50
  - examples/remote-drb.rb
34
51
  - examples/remote-run-script.rb
@@ -65,6 +82,6 @@ rubygems_version: 2.0.4
65
82
  signing_key:
66
83
  specification_version: 4
67
84
  summary: Framework for starting tcp/unix servers and connected clients under one parent
68
- process
85
+ process and on remote hosts
69
86
  test_files: []
70
87
  has_rdoc: