daemon-spawn 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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