daemon-kit 0.1.3
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/History.txt +17 -0
- data/Manifest.txt +62 -0
- data/PostInstall.txt +6 -0
- data/README.textile +94 -0
- data/Rakefile +31 -0
- data/TODO.txt +24 -0
- data/app_generators/daemon_kit/USAGE +7 -0
- data/app_generators/daemon_kit/daemon_kit_generator.rb +120 -0
- data/app_generators/daemon_kit/templates/README +48 -0
- data/app_generators/daemon_kit/templates/Rakefile +4 -0
- data/app_generators/daemon_kit/templates/bin/daemon.erb +7 -0
- data/app_generators/daemon_kit/templates/config/boot.rb +68 -0
- data/app_generators/daemon_kit/templates/config/environment.rb +19 -0
- data/app_generators/daemon_kit/templates/config/environments/development.rb +0 -0
- data/app_generators/daemon_kit/templates/config/environments/production.rb +0 -0
- data/app_generators/daemon_kit/templates/config/environments/test.rb +0 -0
- data/app_generators/daemon_kit/templates/config/initializers/readme +11 -0
- data/app_generators/daemon_kit/templates/libexec/daemon.erb +18 -0
- data/bin/daemon_kit +19 -0
- data/daemon_generators/amqp/USAGE +5 -0
- data/daemon_generators/amqp/amqp_generator.rb +65 -0
- data/daemon_generators/amqp/templates/config/amqp.yml +28 -0
- data/daemon_generators/amqp/templates/config/initializers/amqp.rb +7 -0
- data/daemon_generators/amqp/templates/libexec/daemon.rb +29 -0
- data/daemon_generators/cron/USAGE +5 -0
- data/daemon_generators/cron/cron_generator.rb +64 -0
- data/daemon_generators/cron/templates/config/initializers/cron.rb +7 -0
- data/daemon_generators/cron/templates/libexec/daemon.rb +39 -0
- data/daemon_generators/jabber/USAGE +5 -0
- data/daemon_generators/jabber/jabber_generator.rb +65 -0
- data/daemon_generators/jabber/templates/config/initializers/jabber.rb +7 -0
- data/daemon_generators/jabber/templates/config/jabber.yml +26 -0
- data/daemon_generators/jabber/templates/libexec/daemon.rb +27 -0
- data/lib/daemon_kit.rb +14 -0
- data/lib/daemon_kit/amqp.rb +41 -0
- data/lib/daemon_kit/application.rb +34 -0
- data/lib/daemon_kit/cron.rb +38 -0
- data/lib/daemon_kit/initializer.rb +255 -0
- data/lib/daemon_kit/jabber.rb +172 -0
- data/lib/daemon_kit/patches/force_kill_wait.rb +120 -0
- data/lib/daemon_kit/tasks.rb +2 -0
- data/lib/daemon_kit/tasks/framework.rake +75 -0
- data/rubygems_generators/install_rspec/USAGE +5 -0
- data/rubygems_generators/install_rspec/install_rspec_generator.rb +57 -0
- data/rubygems_generators/install_rspec/templates/spec.rb +11 -0
- data/rubygems_generators/install_rspec/templates/spec/spec.opts +1 -0
- data/rubygems_generators/install_rspec/templates/spec/spec_helper.rb +10 -0
- data/rubygems_generators/install_rspec/templates/tasks/rspec.rake +21 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +71 -0
- data/spec/daemon_kit_spec.rb +7 -0
- data/spec/initializer_spec.rb +31 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +30 -0
- data/tasks/rspec.rake +21 -0
- data/test/test_amqp_generator.rb +48 -0
- data/test/test_cron_generator.rb +45 -0
- data/test/test_daemon-kit_generator.rb +67 -0
- data/test/test_generator_helper.rb +29 -0
- data/test/test_jabber_generator.rb +49 -0
- metadata +168 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
# Shamelessly taken from http://blog.rapleaf.com/dev/?p=19
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'daemons'
|
5
|
+
require 'timeout'
|
6
|
+
|
7
|
+
module Daemons
|
8
|
+
|
9
|
+
class ApplicationGroup
|
10
|
+
|
11
|
+
# We want to redefine find_applications to not rely on
|
12
|
+
# pidfiles (e.g. find application if pidfile is gone)
|
13
|
+
# We recreate the pid files if they're not there.
|
14
|
+
def find_applications(dir)
|
15
|
+
# Find pid_files, like original implementation
|
16
|
+
pid_files = PidFile.find_files(dir, app_name)
|
17
|
+
@monitor = Monitor.find(dir, app_name + '_monitor')
|
18
|
+
pid_files.reject! {|f| f =~ /_monitor.pid$/}
|
19
|
+
|
20
|
+
# Find the missing pids based on the UNIX pids
|
21
|
+
pidfile_pids = pid_files.map {|pf| PidFile.existing(pf).pid}
|
22
|
+
missing_pids = unix_pids - pidfile_pids
|
23
|
+
|
24
|
+
# Create pidfiles that are gone
|
25
|
+
if missing_pids.size > 0
|
26
|
+
puts "[daemons_ext]: #{missing_pids.size} missing pidfiles: " +
|
27
|
+
"#{missing_pids.inspect}... creating pid file(s)."
|
28
|
+
missing_pids.each do |pid|
|
29
|
+
pidfile = PidFile.new(dir, app_name, multiple)
|
30
|
+
pidfile.pid = pid # Doesn't seem to matter if it's a string or Fixnum
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Now get all the pid file again
|
35
|
+
pid_files = PidFile.find_files(dir, app_name)
|
36
|
+
|
37
|
+
return pid_files.map {|f|
|
38
|
+
app = Application.new(self, {}, PidFile.existing(f))
|
39
|
+
setup_app(app)
|
40
|
+
app
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
# Specify :force_kill_wait => (seconds to wait) and this method will
|
45
|
+
# block until the process is dead. It first sends a TERM signal, then
|
46
|
+
# a KILL signal (-9) if the process hasn't died after the wait time.
|
47
|
+
def stop_all(force = false)
|
48
|
+
@monitor.stop if @monitor
|
49
|
+
|
50
|
+
wait = options[:force_kill_wait].to_i
|
51
|
+
if wait > 0
|
52
|
+
puts "[daemons_ext]: Killing #{app_name} with force after #{wait} secs."
|
53
|
+
|
54
|
+
# Send term first, don't delete PID files.
|
55
|
+
@applications.each {|a| a.send_sig('TERM')}
|
56
|
+
|
57
|
+
begin
|
58
|
+
started_at = Time.now
|
59
|
+
Timeout::timeout(wait) do
|
60
|
+
num_pids = unix_pids.size
|
61
|
+
while num_pids > 0
|
62
|
+
time_left = wait - (Time.now - started_at)
|
63
|
+
puts "[daemons_ext]: Waiting #{time_left.round} secs on " +
|
64
|
+
"#{num_pids} #{app_name}(s)..."
|
65
|
+
sleep 1
|
66
|
+
num_pids = unix_pids.size
|
67
|
+
end
|
68
|
+
end
|
69
|
+
rescue Timeout::Error
|
70
|
+
@applications.each {|a| a.send_sig('KILL')}
|
71
|
+
ensure
|
72
|
+
# Delete Pidfiles
|
73
|
+
@applications.each {|a| a.zap!}
|
74
|
+
end
|
75
|
+
|
76
|
+
puts "[daemons_ext]: All #{app_name}(s) dead."
|
77
|
+
else
|
78
|
+
@applications.each {|a|
|
79
|
+
if force
|
80
|
+
begin; a.stop; rescue ::Exception; end
|
81
|
+
else
|
82
|
+
a.stop
|
83
|
+
end
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
# Find UNIX pids based on app_name. CAUTION: This has only been tested on
|
91
|
+
# Mac OS X and CentOS.
|
92
|
+
def unix_pids
|
93
|
+
pids = []
|
94
|
+
x = `ps auxw | grep -v grep | awk '{print $2, $11}' | grep #{app_name}`
|
95
|
+
if x && x.chomp!
|
96
|
+
processes = x.split(/\n/).compact
|
97
|
+
processes = processes.delete_if do |p|
|
98
|
+
pid, name = p.split(/\s/)
|
99
|
+
# We want to make sure that the first part of the process name matches
|
100
|
+
# so that app_name matches app_name_22
|
101
|
+
app_name != name[0..(app_name.length - 1)]
|
102
|
+
end
|
103
|
+
pids = processes.map {|p| p.split(/\s/)[0].to_i}
|
104
|
+
end
|
105
|
+
|
106
|
+
pids
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
class Application
|
112
|
+
|
113
|
+
# Send signal to the process, rescue if process deson't exist
|
114
|
+
def send_sig(sig)
|
115
|
+
Process.kill(sig, @pid.pid) rescue Errno::ESRCH
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
namespace :daemon_kit do
|
2
|
+
namespace :freeze do
|
3
|
+
desc "Lock this application to the current gem (by unpacking it into vendor/daemon_kit)"
|
4
|
+
task :gems do
|
5
|
+
deps = %w()
|
6
|
+
require 'rubygems'
|
7
|
+
require 'rubygems/gem_runner'
|
8
|
+
|
9
|
+
kit = (version = ENV['VERSION']) ?
|
10
|
+
Gem.cache.find_name('daemon-kit', "= #{version}").first :
|
11
|
+
Gem.cache.find_name('daemon-kit').sort_by { |g| g.version }.last
|
12
|
+
|
13
|
+
version ||= kit.version
|
14
|
+
|
15
|
+
unless kit
|
16
|
+
puts "No daemon_kit gem #{version} is installed. Do 'gem list daemon_kit' to see what you have available."
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
|
20
|
+
puts "Freezing the gem for DaemonKit #{kit.version}"
|
21
|
+
rm_rf "vendor/daemon_kit"
|
22
|
+
mkdir_p "vendor/daemon_kit"
|
23
|
+
|
24
|
+
begin
|
25
|
+
chdir("vendor/daemon_kit") do
|
26
|
+
kit.dependencies.select { |g| deps.include? g.name }.each do |g|
|
27
|
+
Gem::GemRunner.new.run(["unpack", g.name, "--version", g.version_requirements.to_s])
|
28
|
+
mv(Dir.glob("#{g.name}*").first, g.name)
|
29
|
+
end
|
30
|
+
|
31
|
+
Gem::GemRunner.new.run(["unpack", "daemon-kit", "--version", "=#{version}"])
|
32
|
+
FileUtils.mv(Dir.glob("daemon-kit*").first, "daemon-kit")
|
33
|
+
end
|
34
|
+
rescue Exception
|
35
|
+
rm_rf "vendor/daemon_kit"
|
36
|
+
raise
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'Lock to latest edge daemon_kit'
|
41
|
+
task :edge do
|
42
|
+
require 'open-uri'
|
43
|
+
#version = ENV["RELEASE"] || "edge"
|
44
|
+
commits = "http://github.com/api/v1/yaml/kennethkalmer/daemon-kit/commits/master"
|
45
|
+
url = "http://github.com/kennethkalmer/daemon-kit/zipball/master"
|
46
|
+
|
47
|
+
rm_rf "vendor/daemon_kit"
|
48
|
+
mkdir_p "vendor/daemon_kit"
|
49
|
+
|
50
|
+
chdir 'vendor/daemon_kit' do
|
51
|
+
latest_revision = YAML.load(open(commits))["commits"].first["id"]
|
52
|
+
|
53
|
+
puts "Downloading DaemonKit from #{url}"
|
54
|
+
File.open('daemon-kit.zip', 'wb') do |dst|
|
55
|
+
open url do |src|
|
56
|
+
while chunk = src.read(4096)
|
57
|
+
dst << chunk
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
puts 'Unpacking DaemonKit'
|
63
|
+
rm_rf 'daemon-kit'
|
64
|
+
`unzip daemon-kit.zip`
|
65
|
+
FileUtils.mv(Dir.glob("kennethkalmer-daemon-kit*").first, "daemon-kit")
|
66
|
+
%w(daemon-kit.zip).each do |goner|
|
67
|
+
rm_f goner
|
68
|
+
end
|
69
|
+
|
70
|
+
touch "REVISION_#{latest_revision}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
class InstallRspecGenerator < RubiGen::Base
|
3
|
+
|
4
|
+
default_options :author => nil
|
5
|
+
|
6
|
+
attr_reader :gem_name, :module_name
|
7
|
+
|
8
|
+
def initialize(runtime_args, runtime_options = {})
|
9
|
+
super
|
10
|
+
@destination_root = File.expand_path(destination_root)
|
11
|
+
@gem_name = base_name
|
12
|
+
@module_name = @gem_name.camelcase
|
13
|
+
extract_options
|
14
|
+
end
|
15
|
+
|
16
|
+
def manifest
|
17
|
+
record do |m|
|
18
|
+
# Ensure appropriate folder(s) exists
|
19
|
+
m.directory 'spec'
|
20
|
+
m.directory 'tasks'
|
21
|
+
|
22
|
+
m.template 'spec.rb', "spec/#{gem_name}_spec.rb"
|
23
|
+
|
24
|
+
m.template_copy_each %w( spec.opts spec_helper.rb ), 'spec'
|
25
|
+
m.file_copy_each %w( rspec.rake ), 'tasks'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
def banner
|
31
|
+
<<-EOS
|
32
|
+
Install rspec BDD testing support.
|
33
|
+
|
34
|
+
Includes a rake task (tasks/rspec.rake) to be loaded by the root Rakefile,
|
35
|
+
which provides a "spec" task.
|
36
|
+
|
37
|
+
USAGE: #{$0} [options]
|
38
|
+
EOS
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_options!(opts)
|
42
|
+
# opts.separator ''
|
43
|
+
# opts.separator 'Options:'
|
44
|
+
# For each option below, place the default
|
45
|
+
# at the top of the file next to "default_options"
|
46
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
47
|
+
# "Some comment about this option",
|
48
|
+
# "Default: none") { |x| options[:author] = x }
|
49
|
+
end
|
50
|
+
|
51
|
+
def extract_options
|
52
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
53
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
54
|
+
# raw instance variable value.
|
55
|
+
# @author = options[:author]
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'spec'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
require 'spec'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'spec/rake/spectask'
|
9
|
+
rescue LoadError
|
10
|
+
puts <<-EOS
|
11
|
+
To use rspec for testing you must install rspec gem:
|
12
|
+
gem install rspec
|
13
|
+
EOS
|
14
|
+
exit(0)
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Run the specs under spec/models"
|
18
|
+
Spec::Rake::SpecTask.new do |t|
|
19
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
20
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
21
|
+
end
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/daemon-kit.rb'}"
|
9
|
+
puts "Loading daemon-kit gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/script/txt2html
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
load File.dirname(__FILE__) + "/../Rakefile"
|
4
|
+
require 'rubyforge'
|
5
|
+
require 'redcloth'
|
6
|
+
require 'syntax/convertors/html'
|
7
|
+
require 'erb'
|
8
|
+
|
9
|
+
download = "http://rubyforge.org/projects/#{$hoe.rubyforge_name}"
|
10
|
+
version = $hoe.version
|
11
|
+
|
12
|
+
def rubyforge_project_id
|
13
|
+
RubyForge.new.configure.autoconfig["group_ids"][$hoe.rubyforge_name]
|
14
|
+
end
|
15
|
+
|
16
|
+
class Fixnum
|
17
|
+
def ordinal
|
18
|
+
# teens
|
19
|
+
return 'th' if (10..19).include?(self % 100)
|
20
|
+
# others
|
21
|
+
case self % 10
|
22
|
+
when 1: return 'st'
|
23
|
+
when 2: return 'nd'
|
24
|
+
when 3: return 'rd'
|
25
|
+
else return 'th'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Time
|
31
|
+
def pretty
|
32
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def convert_syntax(syntax, source)
|
37
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
38
|
+
end
|
39
|
+
|
40
|
+
if ARGV.length >= 1
|
41
|
+
src, template = ARGV
|
42
|
+
template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
|
43
|
+
else
|
44
|
+
puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
|
45
|
+
exit!
|
46
|
+
end
|
47
|
+
|
48
|
+
template = ERB.new(File.open(template).read)
|
49
|
+
|
50
|
+
title = nil
|
51
|
+
body = nil
|
52
|
+
File.open(src) do |fsrc|
|
53
|
+
title_text = fsrc.readline
|
54
|
+
body_text_template = fsrc.read
|
55
|
+
body_text = ERB.new(body_text_template).result(binding)
|
56
|
+
syntax_items = []
|
57
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
58
|
+
ident = syntax_items.length
|
59
|
+
element, syntax, source = $1, $2, $3
|
60
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
61
|
+
"syntax-temp-#{ident}"
|
62
|
+
}
|
63
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
64
|
+
body = RedCloth.new(body_text).to_html
|
65
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
66
|
+
end
|
67
|
+
stat = File.stat(src)
|
68
|
+
created = stat.ctime
|
69
|
+
modified = stat.mtime
|
70
|
+
|
71
|
+
$stdout << template.result(binding)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe DaemonKit::Configuration do
|
4
|
+
before(:each) do
|
5
|
+
@configuration = DaemonKit::Configuration.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should know our environment" do
|
9
|
+
@configuration.environment.should_not be_nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should have a default log path" do
|
13
|
+
@configuration.log_path.should_not be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have a default log level" do
|
17
|
+
@configuration.log_level.should_not be_nil
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
describe DaemonKit::Initializer do
|
24
|
+
|
25
|
+
it "should setup a logger" do
|
26
|
+
pending
|
27
|
+
DaemonKit::Initializer.run(:initialize_logger)
|
28
|
+
DaemonKit.logger.should_not be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|