easy-serve 0.4 → 0.5

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
  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: