daemon-spawn 0.2.0 → 0.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.
data/.autotest ADDED
@@ -0,0 +1,16 @@
1
+ Autotest.add_hook(:initialize) do |at|
2
+ at.clear_mappings
3
+
4
+ at.add_mapping(/.*flymake/) do |f, _|
5
+ []
6
+ end
7
+
8
+ at.add_mapping(%r[lib/daemon-spawn.rb]) do |f, _|
9
+ at.files_matching /^test\/.*_test\.rb$/
10
+ end
11
+
12
+ at.add_mapping(/^test\/.*_test\.rb$/) do |filename, _|
13
+ filename
14
+ end
15
+
16
+ end
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ doc
2
+ pkg
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ === 0.3.0 / 2010-04-18
2
+
3
+ * Typo fix and internal refactoring patches from Emmanuel Gomez
4
+ * Added multi-process spawning and management (inspired by Jontathan Tropper's
5
+ patches)
6
+ * Added LSB-compliance patches from Woody Peterson
7
+ * Added some actual test-coverage :-P
8
+ * Moved examples from "examples" directory to "test/servers"
9
+
1
10
  === 0.2.0 / 2009-04-22
2
11
 
3
12
  * Allow specification of args instead of ARGV so that scripts can
data/Manifest.txt CHANGED
@@ -2,6 +2,8 @@ History.txt
2
2
  Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
- lib/daemon-spawn.rb
6
- test/test_daemon-spawn.rb
7
- examples/echo_server.rb
5
+ lib/daemon_spawn.rb
6
+ test/daemon_spawn_test.rb
7
+ test/multi_daemon_spawn_test.rb
8
+ test/servers/echo_server.rb
9
+ test/servers/simple_server.rb
data/README.txt CHANGED
@@ -46,7 +46,10 @@ The <tt>spawn!</tt> method takes a hash of symbolized keys. At a minimum you
46
46
  _must_ specify the <tt>:working_dir</tt> option. You can also override
47
47
  the default locations for the log and PID files.
48
48
 
49
- See the <tt>examples</tt> directory for working examples.
49
+ If you pass a <tt>:processes</tt> option to the <tt>spawn!</tt>,
50
+ daemon spawn will start that number of processes.
51
+
52
+ See the <tt>test/servers</tt> directory for working examples.
50
53
 
51
54
  === RUNNING A DAEMON:
52
55
 
@@ -68,6 +71,12 @@ method of an instance of your daemon class.
68
71
 
69
72
  None!
70
73
 
74
+ == CONTRIBUTIONS:
75
+
76
+ Feel free to fork this project and send me pull requests with any
77
+ changes that you have. Please note that I won't accept any patches
78
+ with significant formatting changes or ones without tests.
79
+
71
80
  == INSTALL:
72
81
 
73
82
  * sudo gem install daemon-spawn
data/Rakefile CHANGED
@@ -1,12 +1,25 @@
1
1
  # -*- ruby -*-
2
2
 
3
3
  require 'rubygems'
4
- require 'hoe'
5
- require './lib/daemon-spawn.rb'
4
+ require 'jeweler'
5
+ require './lib/daemon_spawn.rb'
6
6
 
7
- Hoe.spec('daemon-spawn') do |p|
8
- p.developer('Alex Vollmer', 'alex.vollmer@gmail.com')
9
- p.rubyforge_name = 'daemon-spawn'
7
+ begin
8
+ require 'jeweler'
9
+ Jeweler::Tasks.new do |gemspec|
10
+ gemspec.name = "daemon-spawn"
11
+ gemspec.summary = "Daemon launching and management made dead simple"
12
+ gemspec.description = %Q[With daemon-spawn you can start, stop and restart processes that run
13
+ in the background. Processed are tracked by a simple PID file written
14
+ to disk.]
15
+ gemspec.rubyforge_project = "daemon-spawn"
16
+ gemspec.email = "alex.vollmer@gmail.com"
17
+ gemspec.homepage = "http://github.com/alexvollmer/daemon-spawn"
18
+ gemspec.authors = ["Alex Vollmer"]
19
+ Jeweler::GemcutterTasks.new
20
+ end
21
+ rescue LoadError
22
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
10
23
  end
11
24
 
12
25
  # vim: syntax=Ruby
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.0
@@ -0,0 +1,58 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{daemon-spawn}
8
+ s.version = "0.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Alex Vollmer"]
12
+ s.date = %q{2010-05-20}
13
+ s.description = %q{With daemon-spawn you can start, stop and restart processes that run
14
+ in the background. Processed are tracked by a simple PID file written
15
+ to disk.}
16
+ s.email = %q{alex.vollmer@gmail.com}
17
+ s.extra_rdoc_files = [
18
+ "README.txt"
19
+ ]
20
+ s.files = [
21
+ ".autotest",
22
+ ".gitignore",
23
+ "History.txt",
24
+ "Manifest.txt",
25
+ "README.txt",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "daemon-spawn.gemspec",
29
+ "lib/daemon_spawn.rb",
30
+ "test/daemon_spawn_test.rb",
31
+ "test/multi_daemon_spawn_test.rb",
32
+ "test/servers/echo_server.rb",
33
+ "test/servers/simple_server.rb"
34
+ ]
35
+ s.homepage = %q{http://github.com/alexvollmer/daemon-spawn}
36
+ s.rdoc_options = ["--charset=UTF-8"]
37
+ s.require_paths = ["lib"]
38
+ s.rubyforge_project = %q{daemon-spawn}
39
+ s.rubygems_version = %q{1.3.7}
40
+ s.summary = %q{Daemon launching and management made dead simple}
41
+ s.test_files = [
42
+ "test/daemon_spawn_test.rb",
43
+ "test/multi_daemon_spawn_test.rb",
44
+ "test/servers/echo_server.rb",
45
+ "test/servers/simple_server.rb"
46
+ ]
47
+
48
+ if s.respond_to? :specification_version then
49
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
50
+ s.specification_version = 3
51
+
52
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
53
+ else
54
+ end
55
+ else
56
+ end
57
+ end
58
+
@@ -1,9 +1,8 @@
1
- require "fileutils"
1
+ require 'fileutils'
2
2
 
3
3
  # Large portions of this were liberally stolen from the
4
4
  # 'simple-daemon' project at http://simple-daemon.rubyforge.org/
5
5
  module DaemonSpawn
6
- VERSION = '0.2.0'
7
6
 
8
7
  def self.usage(msg=nil) #:nodoc:
9
8
  print "#{msg}, " if msg
@@ -19,16 +18,16 @@ module DaemonSpawn
19
18
  end
20
19
 
21
20
  if !File.writable?(File.dirname(daemon.pid_file))
22
- STDERR.puts "Unable to write log file to #{daemon.pid_file}"
21
+ STDERR.puts "Unable to write PID file to #{daemon.pid_file}"
23
22
  exit 1
24
23
  end
25
24
 
26
25
  if daemon.alive? && daemon.singleton
27
- STDERR.puts "An instance of #{daemon.classname} is already " +
26
+ STDERR.puts "An instance of #{daemon.app_name} is already " +
28
27
  "running (PID #{daemon.pid})"
29
- exit 1
28
+ exit 0
30
29
  end
31
-
30
+
32
31
  fork do
33
32
  Process.setsid
34
33
  exit if fork
@@ -43,7 +42,7 @@ module DaemonSpawn
43
42
  trap("TERM") {daemon.stop; exit}
44
43
  daemon.start(args)
45
44
  end
46
- puts "#{daemon.classname} started."
45
+ puts "#{daemon.app_name} started."
47
46
  end
48
47
 
49
48
  def self.stop(daemon) #:nodoc:
@@ -55,30 +54,30 @@ module DaemonSpawn
55
54
  rescue Errno::ECHILD
56
55
  end
57
56
  else
58
- puts "Pid file not found. Is the daemon started?"
59
- exit
57
+ puts "PID file not found. Is the daemon started?"
60
58
  end
61
59
  rescue Errno::ESRCH
62
- puts "Pid file found, but process was not running. The daemon may have died."
60
+ puts "PID file found, but process was not running. The daemon may have died."
63
61
  end
64
62
 
65
63
  def self.status(daemon) #:nodoc:
66
- if daemon.alive?
67
- puts "#{daemon.classname} is running (PID #{PidFile.recall(daemon)})"
68
- else
69
- puts "#{daemon.classname} is NOT running"
70
- end
64
+ puts "#{daemon.app_name} is #{daemon.alive? ? "" : "NOT "}running (PID #{daemon.pid})"
71
65
  end
72
66
 
73
67
  class Base
74
- attr_accessor :log_file, :pid_file, :sync_log, :working_dir, :singleton
68
+ attr_accessor :log_file, :pid_file, :sync_log, :working_dir, :app_name, :singleton, :index
75
69
 
76
- def initialize(opts={ })
77
- raise "You must specify a :working_dir" unless opts[:working_dir]
70
+ def initialize(opts = {})
71
+ raise 'You must specify a :working_dir' unless opts[:working_dir]
78
72
  self.working_dir = opts[:working_dir]
79
-
80
- self.log_file = opts[:log_file] || File.join(self.working_dir, 'logs', self.classname + '.log')
81
- self.pid_file = opts[:pid_file] || File.join(self.working_dir, 'run', self.classname + '.pid')
73
+ self.app_name = opts[:application] || classname
74
+ self.pid_file = opts[:pid_file] || File.join(working_dir, 'tmp', 'pids', app_name + extension)
75
+ self.log_file = opts[:log_file] || File.join(working_dir, 'logs', app_name + '.log')
76
+ self.index = opts[:index] || 0
77
+ if self.index > 0
78
+ self.pid_file += ".#{self.index}"
79
+ self.log_file += ".#{self.index}"
80
+ end
82
81
  self.sync_log = opts[:sync_log]
83
82
  self.singleton = opts[:singleton] || false
84
83
  end
@@ -116,6 +115,22 @@ module DaemonSpawn
116
115
  IO.read(self.pid_file).to_i rescue nil
117
116
  end
118
117
 
118
+ def self.build(options)
119
+ count = options.delete(:processes) || 1
120
+ daemons = []
121
+ count.times do |index|
122
+ daemons << new(options.merge(:index => index))
123
+ end
124
+ daemons
125
+ end
126
+
127
+ def self.find(options)
128
+ pid_file = new(options).pid_file
129
+ basename = File.basename(pid_file).split('.').first
130
+ pid_files = Dir.glob(File.join(File.dirname(pid_file), "#{basename}.*pid*"))
131
+ pid_files.map { |f| new(options.merge(:pid_file => f)) }
132
+ end
133
+
119
134
  # Invoke this method to process command-line args and dispatch
120
135
  # appropriately. Valid options include the following _symbols_:
121
136
  # - <tt>:working_dir</tt> -- the working directory (required)
@@ -127,25 +142,10 @@ module DaemonSpawn
127
142
  # args must begin with 'start', 'stop', 'status', or 'restart'.
128
143
  # The first token will be removed and any remaining arguments
129
144
  # passed to the daemon's start method.
130
- def self.spawn!(opts={ }, args=ARGV)
131
- case args.size > 0 && args.shift
132
- when 'start'
133
- daemon = self.new(opts)
134
- DaemonSpawn.start(daemon, args)
135
- when 'stop'
136
- daemon = self.new(opts)
137
- DaemonSpawn.stop(daemon)
138
- when 'status'
139
- daemon = self.new(opts)
140
- if daemon.alive?
141
- puts "#{daemon.classname} is running (#{daemon.pid})"
142
- else
143
- puts "#{daemon.classname} is NOT running"
144
- end
145
- when 'restart'
146
- daemon = self.new(opts)
147
- DaemonSpawn.stop(daemon)
148
- DaemonSpawn.start(daemon, args)
145
+ def self.spawn!(opts = {}, args = ARGV)
146
+ case args.any? and command = args.shift
147
+ when 'start', 'stop', 'status', 'restart'
148
+ send(command, opts, args)
149
149
  when '-h', '--help', 'help'
150
150
  DaemonSpawn.usage
151
151
  exit
@@ -154,5 +154,43 @@ module DaemonSpawn
154
154
  exit 1
155
155
  end
156
156
  end
157
+
158
+ def self.start(opts, args)
159
+ daemons = find(opts)
160
+ if daemons.empty?
161
+ daemons = build(opts)
162
+ daemons.map { |d| DaemonSpawn.start(d, args) }
163
+ else
164
+ puts "Daemons already started! PIDS: #{daemons.map {|d| d.pid}.join(', ')}"
165
+ exit 1
166
+ end
167
+ end
168
+
169
+ def self.stop(opts, args)
170
+ daemons = find(opts)
171
+ if daemons.empty?
172
+ puts "No PID files found. Is the daemon started?"
173
+ exit 1
174
+ else
175
+ daemons.each { |d| DaemonSpawn.stop(d) }
176
+ end
177
+ end
178
+
179
+ def self.status(opts, args)
180
+ daemons = find(opts)
181
+ if daemons.empty?
182
+ puts 'No PIDs found'
183
+ else
184
+ daemons.each { |d| DaemonSpawn.status(d) }
185
+ end
186
+ end
187
+
188
+ def self.restart(opts, args)
189
+ daemons = find(opts)
190
+ daemons.map do |daemon|
191
+ DaemonSpawn.stop(daemon)
192
+ DaemonSpawn.start(daemon, args)
193
+ end
194
+ end
157
195
  end
158
196
  end
@@ -0,0 +1,102 @@
1
+ require "socket"
2
+ require "test/unit"
3
+
4
+ class DaemonSpawnTest < Test::Unit::TestCase
5
+
6
+ SERVERS = File.join(File.dirname(__FILE__), "servers")
7
+
8
+ def with_socket
9
+ socket = TCPSocket.new('localhost', 5150)
10
+ socket.setsockopt(Socket::SOL_SOCKET,
11
+ Socket::SO_RCVTIMEO,
12
+ [1, 0].pack("l_2"))
13
+
14
+ begin
15
+ yield(socket) if block_given?
16
+ ensure
17
+ socket.close
18
+ end
19
+ end
20
+
21
+ def echo_server(*args)
22
+ `./echo_server.rb #{args.join(' ')}`
23
+ end
24
+
25
+ def while_running
26
+ Dir.chdir(SERVERS) do
27
+ `./echo_server.rb stop`
28
+ assert_match(/EchoServer started./, `./echo_server.rb start 5150`)
29
+ sleep 1
30
+ begin
31
+ with_socket
32
+ ensure
33
+ assert_match(//, `./echo_server.rb stop`)
34
+ assert_raises(Errno::ECONNREFUSED) { TCPSocket.new('localhost', 5150) }
35
+ end
36
+ end
37
+ end
38
+
39
+ def test_daemon_running
40
+ while_running do |socket|
41
+ socket << "foobar\n"
42
+ assert_equal "foobar\n", socket.readline
43
+ end
44
+ end
45
+
46
+ def test_status_running
47
+ while_running do |socket|
48
+ assert_match(/EchoServer is running/, `./echo_server.rb status`)
49
+ end
50
+ end
51
+
52
+ def test_status_not_running
53
+ Dir.chdir(SERVERS) do
54
+ assert_match(/No PIDs found/, `./echo_server.rb status`)
55
+ end
56
+ end
57
+
58
+ def test_start_after_started
59
+ while_running do
60
+ pid = echo_server("status").match(/PID (\d+)/)[1]
61
+ assert_match(/Daemons already started! PIDS: #{pid}/,
62
+ echo_server("start"))
63
+ end
64
+ end
65
+
66
+ def test_stop_after_stopped
67
+ Dir.chdir(SERVERS) do
68
+ assert_match("No PID files found. Is the daemon started?",
69
+ `./echo_server.rb stop`)
70
+ end
71
+ end
72
+
73
+ def test_restart_after_stopped
74
+ Dir.chdir(SERVERS) do
75
+ assert_match(/EchoServer started/, `./echo_server.rb restart 5150`)
76
+ assert_equal(0, $?.exitstatus)
77
+ sleep 1
78
+ with_socket do |socket|
79
+ socket << "foobar\n"
80
+ assert_equal "foobar\n", socket.readline
81
+ end
82
+ end
83
+ end
84
+
85
+ def test_restart_after_started
86
+ Dir.chdir(SERVERS) do
87
+ assert_match(/EchoServer started/, `./echo_server.rb start 5150`)
88
+ assert_equal(0, $?.exitstatus)
89
+ sleep 1
90
+
91
+ assert_match(/EchoServer started/, `./echo_server.rb restart 5150`)
92
+ assert_equal(0, $?.exitstatus)
93
+ sleep 1
94
+
95
+ with_socket do |socket|
96
+ socket << "foobar\n"
97
+ assert_equal "foobar\n", socket.readline
98
+ end
99
+ end
100
+ end
101
+
102
+ end
@@ -0,0 +1,111 @@
1
+ require "test/unit"
2
+ require "tempfile"
3
+
4
+ class MultiDaemonSpawnTest < Test::Unit::TestCase
5
+
6
+ SERVERS = File.join(File.dirname(__FILE__), "servers")
7
+
8
+ def setup
9
+ @tmpfile = Tempfile.new("multi_daemon_spawn_test")
10
+ end
11
+
12
+ def tear_down
13
+ @tmpfile.delete
14
+ end
15
+
16
+ def simple_server(*args)
17
+ `./simple_server.rb #{args.join(" ")}`
18
+ end
19
+
20
+ def current_pids
21
+ regexp = /SimpleServer is running \(PID (\d+)\)/
22
+ pids = simple_server("status").split("\n").map do |line|
23
+ if m = regexp.match(line)
24
+ m[1]
25
+ else
26
+ nil
27
+ end
28
+ end.compact
29
+ end
30
+
31
+ def while_running
32
+ Dir.chdir(SERVERS) do
33
+ simple_server "stop"
34
+ simple_server "start", @tmpfile.path
35
+ sleep 1
36
+ begin
37
+ yield if block_given?
38
+ ensure
39
+ simple_server "stop"
40
+ end
41
+ end
42
+ end
43
+
44
+ def test_start_multiple
45
+ while_running do
46
+ lines = open(@tmpfile.path).readlines
47
+ assert_equal 2, lines.size
48
+ assert lines.member?("SimpleServer (0) started\n")
49
+ assert lines.member?("SimpleServer (1) started\n")
50
+ end
51
+ end
52
+
53
+ def test_status_multiple
54
+ while_running do
55
+ lines = simple_server("status").split("\n")
56
+ lines.each do |line|
57
+ assert_match /SimpleServer is running/, line
58
+ end
59
+ end
60
+ end
61
+
62
+ def test_stop_multiple
63
+ while_running
64
+ Dir.chdir(SERVERS) do
65
+ assert_match /No PIDs found/, simple_server("status")
66
+ end
67
+ end
68
+
69
+ def test_restart_multiple
70
+ while_running do
71
+ pids = current_pids
72
+ simple_server "restart"
73
+ new_pids = current_pids
74
+ assert_not_equal pids.sort, new_pids.sort
75
+ end
76
+ end
77
+
78
+ def test_status_with_one_dead_process
79
+ while_running do
80
+ pids = current_pids
81
+ Process.kill(9, pids[0].to_i)
82
+
83
+ lines = simple_server("status").split("\n")
84
+ assert_equal 2, lines.size
85
+ assert lines.member?("SimpleServer is NOT running (PID #{pids[0]})")
86
+ assert lines.member?("SimpleServer is running (PID #{pids[1]})")
87
+ end
88
+ end
89
+
90
+ def test_restart_with_one_dead_process
91
+ while_running do
92
+ pids = current_pids
93
+ Process.kill(9, pids[0].to_i)
94
+
95
+ lines = simple_server("restart").split("\n")
96
+ assert lines.member?("PID file found, but process was not running. The daemon may have died."), lines.inspect
97
+ assert_equal 2, lines.select { |l| l == "SimpleServer started." }.size
98
+
99
+ new_pids = current_pids
100
+ assert_not_equal new_pids, pids
101
+ end
102
+ end
103
+
104
+ def test_start_after_started
105
+ while_running do
106
+ pids = current_pids
107
+ assert_match(/Daemons already started! PIDS: #{pids.join(', ')}/,
108
+ simple_server("start"))
109
+ end
110
+ end
111
+ end
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "..", "lib"))
4
+
5
+ require "daemon_spawn"
3
6
  require "socket"
4
- require "rubygems"
5
- require "daemon-spawn"
6
7
 
7
8
  # An echo server using daemon-spawn. It starts up local TCP server
8
9
  # socket and repeats each line it receives on the connection. To fire
@@ -21,13 +22,18 @@ class EchoServer < DaemonSpawn::Base
21
22
  def start(args)
22
23
  port = args.empty? ? 0 : args.first.to_i
23
24
  self.server_socket = TCPServer.new('127.0.0.1', port)
25
+ self.server_socket.setsockopt(Socket::SOL_SOCKET,
26
+ Socket::SO_REUSEADDR,
27
+ true)
24
28
  port = self.server_socket.addr[1]
25
29
  puts "EchoServer started on port #{port}"
26
30
  loop do
27
31
  begin
28
32
  client = self.server_socket.accept
33
+ puts "Got a connection from #{client}"
29
34
  while str = client.gets
30
35
  client.write(str)
36
+ puts "Echoed '#{str}' to #{client}"
31
37
  end
32
38
  rescue Errno::ECONNRESET => e
33
39
  STDERR.puts "Client reset connection"
@@ -41,7 +47,7 @@ class EchoServer < DaemonSpawn::Base
41
47
  end
42
48
  end
43
49
 
44
- EchoServer.spawn!(:working_dir => File.join(File.dirname(__FILE__), '..'),
50
+ EchoServer.spawn!(:working_dir => File.join(File.dirname(__FILE__), '..', '..'),
45
51
  :log_file => '/tmp/echo_server.log',
46
52
  :pid_file => '/tmp/echo_server.pid',
47
53
  :sync_log => true,
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "..", "lib"))
4
+
5
+ require "daemon_spawn"
6
+
7
+ class SimpleServer < DaemonSpawn::Base
8
+
9
+ attr_accessor :outfile
10
+
11
+ def start(args)
12
+ abort "USAGE: phrase_server.rb LOGFILE" if args.empty?
13
+ @outfile = args.first
14
+ self.puts "SimpleServer (#{self.index}) started"
15
+ while true # keep running like a real daemon
16
+ sleep 5
17
+ end
18
+ end
19
+
20
+ def puts(str)
21
+ open(@outfile, "a") { |f| f.puts str }
22
+ end
23
+
24
+ def stop
25
+ self.puts "SimpleServer (#{self.index}) stopped"
26
+ end
27
+
28
+ end
29
+
30
+ SimpleServer.spawn!(:working_dir => File.join(File.dirname(__FILE__), '..', '..'),
31
+ :log_file => '/tmp/simple_server.log',
32
+ :pid_file => '/tmp/simple_server.pid',
33
+ :sync_log => true,
34
+ :processes => 2)
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: daemon-spawn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ hash: 19
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Alex Vollmer
@@ -9,75 +15,71 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-11-01 01:00:00 -07:00
18
+ date: 2010-05-20 00:00:00 -07:00
13
19
  default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: hoe
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: 2.3.3
24
- version:
20
+ dependencies: []
21
+
25
22
  description: |-
26
- Daemon launching and management made dead simple.
27
-
28
23
  With daemon-spawn you can start, stop and restart processes that run
29
- in the background. Processed are tracked by a simple PID file written
30
- to disk.
31
-
32
- In addition, you can choose to either execute ruby in your daemonized
33
- process or 'exec' another process altogether (handy for wrapping other
34
- services).
35
- email:
36
- - alex.vollmer@gmail.com
24
+ in the background. Processed are tracked by a simple PID file written
25
+ to disk.
26
+ email: alex.vollmer@gmail.com
37
27
  executables: []
38
28
 
39
29
  extensions: []
40
30
 
41
31
  extra_rdoc_files:
42
- - History.txt
43
- - Manifest.txt
44
32
  - README.txt
45
33
  files:
34
+ - .autotest
35
+ - .gitignore
46
36
  - History.txt
47
37
  - Manifest.txt
48
38
  - README.txt
49
39
  - Rakefile
50
- - lib/daemon-spawn.rb
51
- - test/test_daemon-spawn.rb
52
- - examples/echo_server.rb
40
+ - VERSION
41
+ - daemon-spawn.gemspec
42
+ - lib/daemon_spawn.rb
43
+ - test/daemon_spawn_test.rb
44
+ - test/multi_daemon_spawn_test.rb
45
+ - test/servers/echo_server.rb
46
+ - test/servers/simple_server.rb
53
47
  has_rdoc: true
54
48
  homepage: http://github.com/alexvollmer/daemon-spawn
55
49
  licenses: []
56
50
 
57
51
  post_install_message:
58
52
  rdoc_options:
59
- - --main
60
- - README.txt
53
+ - --charset=UTF-8
61
54
  require_paths:
62
55
  - lib
63
56
  required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
64
58
  requirements:
65
59
  - - ">="
66
60
  - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
67
64
  version: "0"
68
- version:
69
65
  required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
70
67
  requirements:
71
68
  - - ">="
72
69
  - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
73
  version: "0"
74
- version:
75
74
  requirements: []
76
75
 
77
76
  rubyforge_project: daemon-spawn
78
- rubygems_version: 1.3.5
77
+ rubygems_version: 1.3.7
79
78
  signing_key:
80
79
  specification_version: 3
81
80
  summary: Daemon launching and management made dead simple
82
81
  test_files:
83
- - test/test_daemon-spawn.rb
82
+ - test/daemon_spawn_test.rb
83
+ - test/multi_daemon_spawn_test.rb
84
+ - test/servers/echo_server.rb
85
+ - test/servers/simple_server.rb
File without changes