daemontor 0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/{README.rdoc → README.md} +20 -19
- data/Rakefile +2 -25
- data/daemontor.gemspec +18 -0
- data/examples/town_crier.rb +19 -19
- data/lib/daemontor.rb +57 -82
- data/lib/daemontor/version.rb +3 -0
- data/spec/daemontor_spec.rb +27 -27
- data/spec/spec_helper.rb +22 -31
- metadata +40 -83
- data.tar.gz.sig +0 -2
- data/COPYING.txt +0 -674
- data/History.txt +0 -4
- data/Manifest.txt +0 -15
- data/preamble +0 -19
- data/script/console +0 -10
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/spec/spec.opts +0 -1
- data/tasks/rspec.rake +0 -21
- metadata.gz.sig +0 -1
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Dan Wanek
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,33 +1,34 @@
|
|
1
|
-
|
1
|
+
h1. Daemontor
|
2
2
|
|
3
3
|
* http://github.com/zenchild/daemontor
|
4
4
|
|
5
|
-
|
5
|
+
h2. DESCRIPTION
|
6
6
|
|
7
7
|
If you are looking for a package that allows you to simply run a process in the background, Deamontor can help you out. If you're looking for a package that does threading and fine grain process control you'll probably want to look elsewhere.
|
8
8
|
|
9
|
-
|
9
|
+
h2. DEPENDENCIES
|
10
10
|
|
11
11
|
This module depends on the fork system call so it will not run on a Windows OS.
|
12
12
|
|
13
|
-
|
13
|
+
h2. SYNOPSIS
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
```ruby
|
16
|
+
require 'rubygems'
|
17
|
+
require 'daemontor'
|
18
|
+
class Test
|
19
|
+
include Daemontor
|
20
|
+
def initialize
|
21
|
+
daemonize!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
Test.new
|
25
|
+
```
|
24
26
|
|
25
|
-
|
27
|
+
**Also see code in examples/**
|
26
28
|
|
27
|
-
|
29
|
+
h2. INSTALL
|
28
30
|
|
29
|
-
|
31
|
+
`gem install daemontor` or `bundle install`
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
This project is licensed under GPLv3. See COPYING.txt for details.
|
33
|
+
h2. LICENSE
|
34
|
+
This project is licensed under the MIT license (See LICENSE for details).
|
data/Rakefile
CHANGED
@@ -1,25 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'hoe'
|
4
|
-
require 'fileutils'
|
5
|
-
require './lib/daemontor'
|
6
|
-
|
7
|
-
Hoe.plugin :newgem
|
8
|
-
# Hoe.plugin :website
|
9
|
-
# Hoe.plugin :cucumberfeatures
|
10
|
-
|
11
|
-
# Generate all the Rake tasks
|
12
|
-
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
13
|
-
$hoe = Hoe.spec 'daemontor' do
|
14
|
-
self.developer 'Dan Wanek', 'dan.wanek@gmail.com'
|
15
|
-
self.rubyforge_name = nil
|
16
|
-
self.spec_extras[:licenses] = "GPLv3"
|
17
|
-
# self.extra_deps = [['activesupport','>= 2.0.2']]
|
18
|
-
end
|
19
|
-
|
20
|
-
require 'newgem/tasks'
|
21
|
-
Dir['tasks/**/*.rake'].each { |t| load t }
|
22
|
-
|
23
|
-
# TODO - want other tests/tasks run by default? Add them to the list
|
24
|
-
# remove_task :default
|
25
|
-
# task :default => [:spec, :features]
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
data/daemontor.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/daemontor/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Dan Wanek"]
|
6
|
+
gem.email = ["dan.wanek@gmail.com"]
|
7
|
+
gem.description = %q{Module to aid in running background processes.}
|
8
|
+
gem.summary = %q{If you are looking for a gem that allows you to simply run a process in the background, Deamontor can help you out. If you're looking for a package that does threading and fine grain process control you'll probably want to look elsewhere.}
|
9
|
+
gem.homepage = "http://github.com/zenchild/daemontor"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.extra_rdoc_files = %w(README.md)
|
13
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
14
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
|
+
gem.name = "daemontor"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = Daemontor::VERSION
|
18
|
+
end
|
data/examples/town_crier.rb
CHANGED
@@ -2,27 +2,27 @@ $: << '../lib'
|
|
2
2
|
require 'daemontor'
|
3
3
|
|
4
4
|
class TownCrier
|
5
|
-
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
$DEBUG = true # Set this so output doesn't go to the background in the example.
|
9
|
-
pid = Process.pid
|
10
|
-
daemonize!
|
11
|
-
puts "Process running in background as PID: #{Process.pid}"
|
12
|
-
cry
|
13
|
-
end
|
5
|
+
include Daemontor
|
14
6
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
7
|
+
def initialize
|
8
|
+
$DEBUG = true # Set this so output doesn't go to the background in the example.
|
9
|
+
pid = Process.pid
|
10
|
+
daemonize!
|
11
|
+
puts "Process running in background as PID: #{Process.pid}"
|
12
|
+
cry
|
13
|
+
end
|
22
14
|
|
23
|
-
|
24
|
-
|
25
|
-
|
15
|
+
def cry
|
16
|
+
loop do
|
17
|
+
puts "It's #{Time.now.to_s} and all is well"
|
18
|
+
puts "Kill the process with 'kill -INT #{Process.pid}'"
|
19
|
+
sleep 10
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def pid
|
24
|
+
return Process.pid
|
25
|
+
end
|
26
26
|
end
|
27
27
|
|
28
28
|
|
data/lib/daemontor.rb
CHANGED
@@ -1,91 +1,66 @@
|
|
1
|
-
|
2
|
-
# Copyright © 2009 Dan Wanek <dan.wanek@gmail.com>
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# This file is part of Daemontor.
|
6
|
-
#
|
7
|
-
# Daemontor is free software: you can redistribute it and/or
|
8
|
-
# modify it under the terms of the GNU General Public License as published
|
9
|
-
# by the Free Software Foundation, either version 3 of the License, or (at
|
10
|
-
# your option) any later version.
|
11
|
-
#
|
12
|
-
# Daemontor is distributed in the hope that it will be useful,
|
13
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
15
|
-
# Public License for more details.
|
16
|
-
#
|
17
|
-
# You should have received a copy of the GNU General Public License along
|
18
|
-
# with Daemontor. If not, see <http://www.gnu.org/licenses/>.
|
19
|
-
#############################################################################
|
20
|
-
$:.unshift(File.dirname(__FILE__)) unless
|
21
|
-
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
1
|
+
require 'daemontor/version'
|
22
2
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
Thanks to the PickAxe book for good process handling information as well as
|
31
|
-
Travis Whitton's Daemonize module: http://grub.ath.cx/daemonize/
|
32
|
-
=end
|
3
|
+
# This module's purpose is to daemonize processes so they can be run in the
|
4
|
+
# background like a standard UNIX daemon. When Daemontor::daemonize is called
|
5
|
+
# the parent process fork()s a new child process and calls Process.detach so we
|
6
|
+
# don't have to wait for the child process to exit. The parent process then
|
7
|
+
# exits and the child process goes happily on. Since we are calling
|
8
|
+
# Process.detach we do not need to do a double-fork.
|
9
|
+
#
|
10
|
+
# Thanks to the PickAxe book for good process handling information as well as
|
11
|
+
# hints from Travis Whitton's Daemonize module: http://grub.ath.cx/daemonize/
|
33
12
|
module Daemontor
|
34
|
-
VERSION = '0.0.1'
|
35
|
-
|
36
|
-
# This is the function that makes it all happen. By default the parent process
|
37
|
-
# will be killed off. If you want to do something with the parent afterword pass a
|
38
|
-
# boolean true value and you will get access to the process back once the child is
|
39
|
-
# detached.
|
40
|
-
def daemonize!(keep_parent_alive = false)
|
41
|
-
puts "Doing fork " + Process.pid.to_s if $DEBUG
|
42
|
-
|
43
|
-
|
44
|
-
if((cpid = fork).nil?)
|
45
|
-
# Only the child processes should get here
|
46
|
-
trap("INT", proc {p_int} )
|
47
|
-
trap("QUIT", proc {p_quit} )
|
48
|
-
trap("TERM", proc {p_term} )
|
49
|
-
trap("KILL", proc {p_kill} )
|
50
|
-
unless $DEBUG
|
51
|
-
STDIN.reopen "/dev/null"
|
52
|
-
STDOUT.reopen "/dev/null", "a"
|
53
|
-
STDERR.reopen STDOUT
|
54
|
-
end
|
55
|
-
else
|
56
|
-
# Only the parent processes should get here. We detach from a specific
|
57
|
-
# PID so we don't globally detach from all PIDs. This may be handy when you need some
|
58
|
-
# children to return and some not to. The logic isn't here to do that yet, but it
|
59
|
-
# should be relatively easy to implement with this already in place.
|
60
|
-
puts "Detaching from child process #{cpid}" if $DEBUG
|
61
|
-
Process.detach(cpid)
|
62
|
-
exit unless keep_parent_alive
|
63
|
-
end
|
64
|
-
return cpid
|
65
|
-
end
|
66
13
|
|
14
|
+
# This is the function that makes it all happen. By default the parent process
|
15
|
+
# will be killed off. If you want to do something with the parent afterward
|
16
|
+
# pass a boolean true value and you will get access to the process once the
|
17
|
+
# child is detached.
|
18
|
+
def daemonize!(keep_parent_alive = false)
|
19
|
+
puts "Doing fork " + Process.pid.to_s if $DEBUG
|
20
|
+
if((cpid = fork).nil?)
|
21
|
+
# Only the child processes should get here
|
22
|
+
trap("INT", proc {p_int} )
|
23
|
+
trap("QUIT", proc {p_quit} )
|
24
|
+
trap("TERM", proc {p_term} )
|
25
|
+
trap("KILL", proc {p_kill} )
|
26
|
+
unless $DEBUG
|
27
|
+
STDIN.reopen "/dev/null"
|
28
|
+
STDOUT.reopen "/dev/null", "a"
|
29
|
+
STDERR.reopen STDOUT
|
30
|
+
end
|
31
|
+
else
|
32
|
+
# Only the parent processes should get here. We detach from a specific
|
33
|
+
# PID so we don't globally detach from all PIDs. This may be handy when you need some
|
34
|
+
# children to return and some not to. The logic isn't here to do that yet, but it
|
35
|
+
# should be relatively easy to implement with this already in place.
|
36
|
+
puts "Detaching from child process #{cpid}" if $DEBUG
|
37
|
+
Process.detach(cpid)
|
38
|
+
exit unless keep_parent_alive
|
39
|
+
end
|
40
|
+
return cpid
|
41
|
+
end
|
67
42
|
|
68
|
-
|
69
|
-
|
70
|
-
|
43
|
+
# *********************************************************************************
|
44
|
+
# You might want to overide the following methods to do something a little smarter.
|
45
|
+
# *********************************************************************************
|
71
46
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
47
|
+
def p_int
|
48
|
+
warn "Process interupt recieved. Killing process"
|
49
|
+
p_kill
|
50
|
+
end
|
76
51
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
52
|
+
def p_quit
|
53
|
+
warn "Process quit recieved. Killing process"
|
54
|
+
p_kill
|
55
|
+
end
|
81
56
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
57
|
+
def p_term
|
58
|
+
warn "Process termination recieved. Killing process"
|
59
|
+
p_kill
|
60
|
+
end
|
86
61
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
62
|
+
def p_kill
|
63
|
+
warn "Killing process #{Process.pid.to_s}"
|
64
|
+
exit
|
65
|
+
end
|
91
66
|
end
|
data/spec/daemontor_spec.rb
CHANGED
@@ -4,32 +4,32 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
4
4
|
# it should serve its purpose.
|
5
5
|
describe "Test basic functionality of Daemontor" do
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
it "should spawn a new daemon and kill it" do
|
8
|
+
begin
|
9
|
+
master_pid = Process.pid.to_s
|
10
|
+
pids = []
|
11
|
+
puts "*** PID: #{Process.pid}"
|
12
|
+
tester = TesterClass.new
|
13
|
+
puts "****** PID: #{Process.pid}"
|
14
|
+
retval = false
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
16
|
+
if( Process.pid.to_s == master_pid )
|
17
|
+
puts "IN MASTER LOGIC: Child => #{tester.cpid}"
|
18
|
+
pids << tester.cpid.to_s
|
19
|
+
pids.each do |pid|
|
20
|
+
puts "KILLING PID: #{pid}"
|
21
|
+
Process.kill("INT", pid.to_i)
|
22
|
+
end
|
23
|
+
retval = true
|
24
|
+
else
|
25
|
+
puts "IN CHILD LOGIC"
|
26
|
+
tester.do_stuff
|
27
|
+
end
|
28
|
+
rescue ChildEnded => e
|
29
|
+
puts "Child ended appropriately"
|
30
|
+
retval = true
|
31
|
+
end
|
32
|
+
# if we get to this point lets just call it success :)
|
33
|
+
retval.should be_true
|
34
|
+
end
|
35
35
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,42 +1,33 @@
|
|
1
|
-
begin
|
2
|
-
require 'spec'
|
3
|
-
rescue LoadError
|
4
|
-
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
5
|
-
gem 'rspec'
|
6
|
-
require 'spec'
|
7
|
-
end
|
8
|
-
|
9
1
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
10
2
|
require 'daemontor'
|
11
3
|
|
12
|
-
|
13
4
|
class TesterClass
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
5
|
+
include Daemontor
|
6
|
+
attr_reader :cpid
|
7
|
+
def initialize
|
8
|
+
$DEBUG = true # Set this so output doesn't go to the background in the example.
|
9
|
+
pid = Process.pid
|
10
|
+
@cpid = daemonize!(true)
|
11
|
+
@run = true
|
12
|
+
end
|
22
13
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
14
|
+
def do_stuff
|
15
|
+
while @run do
|
16
|
+
puts "Hello, I'm process #{Process.pid}"
|
17
|
+
sleep 15
|
18
|
+
end
|
19
|
+
end
|
29
20
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
21
|
+
def p_int
|
22
|
+
warn "Process interupt recieved. Killing process"
|
23
|
+
raise ChildEnded
|
24
|
+
exit
|
25
|
+
end
|
35
26
|
|
36
27
|
end
|
37
28
|
|
38
29
|
class ChildEnded < StandardError
|
39
|
-
|
40
|
-
|
41
|
-
|
30
|
+
def message
|
31
|
+
"Child Ended"
|
32
|
+
end
|
42
33
|
end
|