kennethkalmer-daemon-kit 0.1.7.5 → 0.1.7.7
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +21 -0
- data/Manifest.txt +16 -6
- data/README.rdoc +1 -0
- data/Rakefile +2 -1
- data/TODO.txt +13 -9
- data/app_generators/daemon_kit/daemon_kit_generator.rb +11 -4
- data/app_generators/daemon_kit/templates/config/environment.rb +3 -3
- data/app_generators/daemon_kit/templates/config/environments/development.rb +2 -0
- data/app_generators/daemon_kit/templates/config/environments/production.rb +2 -0
- data/app_generators/daemon_kit/templates/config/environments/test.rb +2 -0
- data/app_generators/daemon_kit/templates/script/generate +1 -1
- data/bin/daemon_kit +1 -2
- data/daemon_generators/cron/templates/config/initializers/cron.rb +5 -1
- data/daemon_generators/cron/templates/libexec/daemon.rb +6 -2
- data/daemon_generators/cucumber/USAGE +11 -0
- data/daemon_generators/cucumber/cucumber_generator.rb +38 -0
- data/daemon_generators/cucumber/templates/cucumber +8 -0
- data/daemon_generators/cucumber/templates/cucumber.rake +13 -0
- data/daemon_generators/cucumber/templates/cucumber_environment.rb +2 -0
- data/daemon_generators/cucumber/templates/env.rb +7 -0
- data/{rubygems_generators/install_rspec → daemon_generators/rspec}/USAGE +0 -0
- data/{rubygems_generators/install_rspec/install_rspec_generator.rb → daemon_generators/rspec/rspec_generator.rb} +7 -9
- data/{rubygems_generators/install_rspec → daemon_generators/rspec}/templates/spec.rb +0 -0
- data/{rubygems_generators/install_rspec → daemon_generators/rspec}/templates/spec/spec.opts +0 -0
- data/{rubygems_generators/install_rspec → daemon_generators/rspec}/templates/spec/spec_helper.rb +0 -1
- data/{rubygems_generators/install_rspec → daemon_generators/rspec}/templates/tasks/rspec.rake +0 -0
- data/lib/daemon_kit.rb +5 -1
- data/lib/daemon_kit/application.rb +5 -1
- data/lib/daemon_kit/core_ext/configurable.rb +96 -0
- data/lib/daemon_kit/cron.rb +18 -8
- data/lib/daemon_kit/cucumber/world.rb +38 -0
- data/lib/daemon_kit/em.rb +43 -0
- data/lib/daemon_kit/initializer.rb +44 -3
- data/lib/daemon_kit/tasks/framework.rake +1 -1
- data/spec/configurable_spec.rb +56 -0
- metadata +30 -10
data/History.txt
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
== 0.1.7.8 2009-06-22
|
2
|
+
|
3
|
+
* Optional logging of all exceptions when the daemon process dies
|
4
|
+
unexpectedly
|
5
|
+
* Update generated environment.rb to reflect new backtraces option
|
6
|
+
|
7
|
+
== 0.1.7.7 2009-06-22
|
8
|
+
|
9
|
+
* Fixed compatibility with rufus-scheduler-2.0.0 (or newer) in cron
|
10
|
+
generator
|
11
|
+
* Started central eventmachine reactor management code
|
12
|
+
* Now depends on eventmachine
|
13
|
+
|
14
|
+
== 0.1.7.6 (Not released)
|
15
|
+
|
16
|
+
* Support for cucumber
|
17
|
+
* Fixed issue in daemon_kit:upgrade task
|
18
|
+
* Moved rspec generator into new home
|
19
|
+
* Removed conflicting rubigen generator, messed with our script directory
|
20
|
+
* Fixed bug where environment.rb overwrites some --config values (reported by Josh Owens)
|
21
|
+
|
1
22
|
== 0.1.7.5 2009-06-08
|
2
23
|
|
3
24
|
* New AbstractLogger
|
data/Manifest.txt
CHANGED
@@ -35,6 +35,12 @@ daemon_generators/cron/USAGE
|
|
35
35
|
daemon_generators/cron/cron_generator.rb
|
36
36
|
daemon_generators/cron/templates/config/initializers/cron.rb
|
37
37
|
daemon_generators/cron/templates/libexec/daemon.rb
|
38
|
+
daemon_generators/cucumber/USAGE
|
39
|
+
daemon_generators/cucumber/cucumber_generator.rb
|
40
|
+
daemon_generators/cucumber/templates/cucumber
|
41
|
+
daemon_generators/cucumber/templates/cucumber.rake
|
42
|
+
daemon_generators/cucumber/templates/cucumber_environment.rb
|
43
|
+
daemon_generators/cucumber/templates/env.rb
|
38
44
|
daemon_generators/deploy_capistrano/deploy_capistrano_generator.rb
|
39
45
|
daemon_generators/deploy_capistrano/templates/Capfile
|
40
46
|
daemon_generators/deploy_capistrano/templates/USAGE
|
@@ -53,6 +59,12 @@ daemon_generators/nanite_agent/templates/config/initializers/nanite_agent.rb
|
|
53
59
|
daemon_generators/nanite_agent/templates/config/nanite.yml
|
54
60
|
daemon_generators/nanite_agent/templates/lib/actors/sample.rb
|
55
61
|
daemon_generators/nanite_agent/templates/libexec/daemon.rb
|
62
|
+
daemon_generators/rspec/USAGE
|
63
|
+
daemon_generators/rspec/rspec_generator.rb
|
64
|
+
daemon_generators/rspec/templates/spec.rb
|
65
|
+
daemon_generators/rspec/templates/spec/spec.opts
|
66
|
+
daemon_generators/rspec/templates/spec/spec_helper.rb
|
67
|
+
daemon_generators/rspec/templates/tasks/rspec.rake
|
56
68
|
lib/daemon_kit.rb
|
57
69
|
lib/daemon_kit/abstract_logger.rb
|
58
70
|
lib/daemon_kit/amqp.rb
|
@@ -62,9 +74,12 @@ lib/daemon_kit/commands/console.rb
|
|
62
74
|
lib/daemon_kit/config.rb
|
63
75
|
lib/daemon_kit/console_daemon.rb
|
64
76
|
lib/daemon_kit/core_ext.rb
|
77
|
+
lib/daemon_kit/core_ext/configurable.rb
|
65
78
|
lib/daemon_kit/core_ext/string.rb
|
66
79
|
lib/daemon_kit/cron.rb
|
80
|
+
lib/daemon_kit/cucumber/world.rb
|
67
81
|
lib/daemon_kit/deployment/capistrano.rb
|
82
|
+
lib/daemon_kit/em.rb
|
68
83
|
lib/daemon_kit/error_handlers/base.rb
|
69
84
|
lib/daemon_kit/error_handlers/hoptoad.rb
|
70
85
|
lib/daemon_kit/error_handlers/mail.rb
|
@@ -80,12 +95,6 @@ lib/daemon_kit/tasks/framework.rake
|
|
80
95
|
lib/daemon_kit/tasks/god.rake
|
81
96
|
lib/daemon_kit/tasks/log.rake
|
82
97
|
lib/daemon_kit/tasks/monit.rake
|
83
|
-
rubygems_generators/install_rspec/USAGE
|
84
|
-
rubygems_generators/install_rspec/install_rspec_generator.rb
|
85
|
-
rubygems_generators/install_rspec/templates/spec.rb
|
86
|
-
rubygems_generators/install_rspec/templates/spec/spec.opts
|
87
|
-
rubygems_generators/install_rspec/templates/spec/spec_helper.rb
|
88
|
-
rubygems_generators/install_rspec/templates/tasks/rspec.rake
|
89
98
|
script/console
|
90
99
|
script/destroy
|
91
100
|
script/generate
|
@@ -93,6 +102,7 @@ script/txt2html
|
|
93
102
|
spec/abstract_logger_spec.rb
|
94
103
|
spec/argument_spec.rb
|
95
104
|
spec/config_spec.rb
|
105
|
+
spec/configurable_spec.rb
|
96
106
|
spec/daemon_kit_spec.rb
|
97
107
|
spec/error_handlers_spec.rb
|
98
108
|
spec/fixtures/env.yml
|
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -10,7 +10,8 @@ $hoe = Hoe.new('daemon-kit', DaemonKit::VERSION) do |p|
|
|
10
10
|
p.post_install_message = IO.read( 'PostInstall.txt' ) # TODO remove if post-install message not required
|
11
11
|
p.rubyforge_name = 'kit' # TODO this is default value
|
12
12
|
p.extra_deps = [
|
13
|
-
['rubigen', '>= 1.5.2']
|
13
|
+
['rubigen', '>= 1.5.2'],
|
14
|
+
['eventmachine', '>=0.12.8']
|
14
15
|
]
|
15
16
|
p.extra_dev_deps = [
|
16
17
|
['newgem', ">= #{::Newgem::VERSION}"]
|
data/TODO.txt
CHANGED
@@ -1,8 +1,19 @@
|
|
1
|
-
DaemonKit TODO List
|
2
|
-
===================
|
1
|
+
= DaemonKit TODO List
|
3
2
|
|
4
3
|
This is purely a drop in the bucket of what has to come...
|
5
4
|
|
5
|
+
== Eye on 0.2
|
6
|
+
|
7
|
+
* Support for dropping privileges
|
8
|
+
* Support for chroot'ing
|
9
|
+
* Altering process names (fully and temporary appending)
|
10
|
+
* bleak_house support
|
11
|
+
* Support for tweaking REE environment variables prior to launch (bash wrapper)
|
12
|
+
* Clustering support (run multiple workers out of same project)
|
13
|
+
* Full 1.9 support in the framework
|
14
|
+
|
15
|
+
== Later
|
16
|
+
|
6
17
|
* [IN PROGRESS] Error handling to the degree Rails does
|
7
18
|
* Easy configuration of an ORM of choice, including patching it if needed (ActiveRecord *cough*)
|
8
19
|
* Improved generators for creating skeleton daemons:
|
@@ -12,9 +23,6 @@ This is purely a drop in the bucket of what has to come...
|
|
12
23
|
* Queue (SQS, AMQP, etc) pollers
|
13
24
|
* Rake tasks for generating:
|
14
25
|
* Sys-V style init scripts
|
15
|
-
* Support for dropping privileges
|
16
|
-
* Support for chroot'ing
|
17
|
-
* Improved and cleaned up logging, support logrotating (via HUP)
|
18
26
|
* Plenty of docs, seriously a lot of docs
|
19
27
|
* Specs & features, tons of them too
|
20
28
|
* Integration tests for the specific daemons
|
@@ -25,9 +33,5 @@ This is purely a drop in the bucket of what has to come...
|
|
25
33
|
* Some activesupport-esque functions until activesupport 3.0 hits the streets
|
26
34
|
* DRY up the following:
|
27
35
|
* Loading configuration files for the daemons
|
28
|
-
* Altering process names (fully and temporary appending)
|
29
|
-
* bleak_house support
|
30
|
-
* Support for tweaking REE environment variables prior to launch (bash wrapper)
|
31
|
-
* Clustering support (run multiple workers out of same project)
|
32
36
|
|
33
37
|
* DON'T FORGET 1.9 SUPPORT
|
@@ -12,6 +12,7 @@ class DaemonKitGenerator < RubiGen::Base
|
|
12
12
|
attr_reader :daemon_name
|
13
13
|
attr_reader :installer
|
14
14
|
attr_reader :deployer
|
15
|
+
attr_reader :cucumber
|
15
16
|
|
16
17
|
def initialize(runtime_args, runtime_options = {})
|
17
18
|
super
|
@@ -87,7 +88,10 @@ class DaemonKitGenerator < RubiGen::Base
|
|
87
88
|
m.directory "tasks"
|
88
89
|
|
89
90
|
# Tests
|
90
|
-
m.dependency "
|
91
|
+
m.dependency "rspec", [daemon_name], :destination => destination_root, :collision => :force
|
92
|
+
if cucumber
|
93
|
+
m.dependency "cucumber", [], :destination => destination_root, :collision => :force
|
94
|
+
end
|
91
95
|
|
92
96
|
# Deployers
|
93
97
|
unless deployer == 'none'
|
@@ -98,9 +102,6 @@ class DaemonKitGenerator < RubiGen::Base
|
|
98
102
|
m.directory "log"
|
99
103
|
m.directory "tmp"
|
100
104
|
m.directory "vendor"
|
101
|
-
|
102
|
-
m.dependency "install_rubigen_scripts", [destination_root, 'daemon_kit'],
|
103
|
-
:shebang => options[:shebang], :collision => :force
|
104
105
|
end
|
105
106
|
end
|
106
107
|
|
@@ -136,6 +137,11 @@ EOS
|
|
136
137
|
options[:deployer] = deploy
|
137
138
|
end
|
138
139
|
|
140
|
+
opts.on("--cucumber",
|
141
|
+
"Install cucumber.") do
|
142
|
+
options[:cucumber] = true
|
143
|
+
end
|
144
|
+
|
139
145
|
opts.on("-r", "--ruby=path", String,
|
140
146
|
"Path to the Ruby binary of your choice (otherwise scripts use env, dispatchers current path).",
|
141
147
|
"Default: #{DEFAULT_SHEBANG}") { |x| options[:shebang] = x }
|
@@ -149,6 +155,7 @@ EOS
|
|
149
155
|
# @author = options[:author]
|
150
156
|
@installer = options[:installer] || 'default'
|
151
157
|
@deployer = (options[:deployer] || 'none').strip
|
158
|
+
@cucumber = options[:cucumber] || false
|
152
159
|
end
|
153
160
|
|
154
161
|
end
|
@@ -11,12 +11,12 @@ DaemonKit::Initializer.run do |config|
|
|
11
11
|
# The name of the daemon as reported by process monitoring tools
|
12
12
|
config.daemon_name = '<%= daemon_name %>'
|
13
13
|
|
14
|
-
# Uncomment to allow multiple instances to run
|
15
|
-
# config.mulitple = true
|
16
|
-
|
17
14
|
# Force the daemon to be killed after X seconds from asking it to
|
18
15
|
# config.force_kill_wait = 30
|
19
16
|
|
17
|
+
# Log backraces when a thread/daemon dies (Recommended)
|
18
|
+
# config.backtraces = true
|
19
|
+
|
20
20
|
# Configure the safety net (see DaemonKit::Safety)
|
21
21
|
# config.safety_net.handler = :mail # (or :hoptoad )
|
22
22
|
# config.safety_net.mail.host = 'localhost'
|
data/bin/daemon_kit
CHANGED
@@ -13,7 +13,6 @@ require 'rubigen/scripts/generate'
|
|
13
13
|
RubiGen::Base.use_application_sources! :rubygems
|
14
14
|
RubiGen::Base.prepend_sources(*[
|
15
15
|
RubiGen::PathSource.new(:app, File.join(File.dirname(__FILE__), "..", "app_generators")),
|
16
|
-
RubiGen::PathSource.new(:app, File.join(File.dirname(__FILE__), "..", "daemon_generators"))
|
17
|
-
RubiGen::PathSource.new(:app, File.join(File.dirname(__FILE__), "..", "rubygems_generators"))
|
16
|
+
RubiGen::PathSource.new(:app, File.join(File.dirname(__FILE__), "..", "daemon_generators"))
|
18
17
|
])
|
19
18
|
RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'daemon_kit')
|
@@ -1,7 +1,11 @@
|
|
1
1
|
begin
|
2
|
-
require 'rufus
|
2
|
+
require 'rufus/scheduler'
|
3
3
|
rescue LoadError => e
|
4
4
|
$stderr.puts "Missing rufus-scheduler gem. Please run 'gem install rufus-scheduler'."
|
5
5
|
exit 1
|
6
6
|
end
|
7
7
|
|
8
|
+
if Rufus::Scheduler::VERSION < "2.0.0"
|
9
|
+
$stderr.puts "Requires rufus-scheduler-2.0.0 or later"
|
10
|
+
exit 1
|
11
|
+
end
|
@@ -15,13 +15,17 @@ end
|
|
15
15
|
# An instance of the scheduler is available through
|
16
16
|
# DaemonKit::Cron.scheduler
|
17
17
|
|
18
|
+
# To make use of the EventMachine-powered scheduler, uncomment the
|
19
|
+
# line below *before* adding any schedules.
|
20
|
+
# DaemonKit::EM.run
|
21
|
+
|
18
22
|
# Some samples to get you going:
|
19
23
|
|
20
24
|
# Will call #regenerate_monthly_report in 3 days from starting up
|
21
25
|
#DaemonKit::Cron.scheduler.in("3d") do
|
22
26
|
# regenerate_monthly_report()
|
23
27
|
#end
|
24
|
-
#
|
28
|
+
#
|
25
29
|
#DaemonKit::Cron.scheduler.every "10m10s" do
|
26
30
|
# check_score(favourite_team) # every 10 minutes and 10 seconds
|
27
31
|
#end
|
@@ -35,5 +39,5 @@ DaemonKit::Cron.scheduler.every("1m") do
|
|
35
39
|
DaemonKit.logger.debug "Scheduled task completed at #{Time.now}"
|
36
40
|
end
|
37
41
|
|
38
|
-
# Run our 'cron'
|
42
|
+
# Run our 'cron' dameon, suspending the current thread
|
39
43
|
DaemonKit::Cron.run
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Description:
|
2
|
+
Sets up Cucumber in your daemon-kit project. After running this generator you will
|
3
|
+
get a new rake task called features.
|
4
|
+
|
5
|
+
This also generates the necessary files in the features directory.
|
6
|
+
|
7
|
+
Also see the feature generator, which you can use to generate skeletons
|
8
|
+
for new features.
|
9
|
+
|
10
|
+
Examples:
|
11
|
+
`./script/generate cucumber`
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'cucumber/version'
|
3
|
+
|
4
|
+
# This generator bootstraps a Rails project for use with Cucumber
|
5
|
+
class CucumberGenerator < RubiGen::Base
|
6
|
+
DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
|
7
|
+
Config::CONFIG['ruby_install_name'])
|
8
|
+
|
9
|
+
def manifest
|
10
|
+
record do |m|
|
11
|
+
m.directory 'features/step_definitions'
|
12
|
+
m.template 'cucumber_environment.rb', 'config/environments/cucumber.rb',
|
13
|
+
:assigns => { :cucumber_version => ::Cucumber::VERSION::STRING }
|
14
|
+
|
15
|
+
m.directory 'features/support'
|
16
|
+
|
17
|
+
#if options[:spork]
|
18
|
+
# m.template 'spork_env.rb', 'features/support/env.rb'
|
19
|
+
#else
|
20
|
+
m.template 'env.rb', 'features/support/env.rb'
|
21
|
+
#end
|
22
|
+
|
23
|
+
m.directory 'tasks'
|
24
|
+
m.template 'cucumber.rake', 'tasks/cucumber.rake'
|
25
|
+
|
26
|
+
m.file 'cucumber', 'script/cucumber', {
|
27
|
+
:chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang]
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def banner
|
35
|
+
"Usage: #{$0} cucumber"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
begin
|
2
|
+
require 'cucumber/rake/task'
|
3
|
+
|
4
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
5
|
+
t.fork = true
|
6
|
+
t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
|
7
|
+
end
|
8
|
+
rescue LoadError
|
9
|
+
desc 'Cucumber rake task not available'
|
10
|
+
task :features do
|
11
|
+
abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Sets up the DaemonKit environment for Cucumber
|
2
|
+
ENV["DAEMON_ENV"] ||= "cucumber"
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
|
4
|
+
require 'daemon_kit/cucumber/world'
|
5
|
+
|
6
|
+
# Comment out the next line if you don't want Cucumber Unicode support
|
7
|
+
require 'cucumber/formatter/unicode'
|
File without changes
|
@@ -1,10 +1,8 @@
|
|
1
1
|
|
2
|
-
class
|
3
|
-
|
4
|
-
default_options :author => nil
|
5
|
-
|
2
|
+
class RspecGenerator < RubiGen::Base
|
3
|
+
|
6
4
|
attr_reader :gem_name, :module_name
|
7
|
-
|
5
|
+
|
8
6
|
def initialize(runtime_args, runtime_options = {})
|
9
7
|
super
|
10
8
|
@destination_root = File.expand_path(destination_root)
|
@@ -20,7 +18,7 @@ class InstallRspecGenerator < RubiGen::Base
|
|
20
18
|
m.directory 'tasks'
|
21
19
|
|
22
20
|
m.template 'spec.rb', "spec/#{gem_name}_spec.rb"
|
23
|
-
|
21
|
+
|
24
22
|
m.template_copy_each %w( spec.opts spec_helper.rb ), 'spec'
|
25
23
|
m.file_copy_each %w( rspec.rake ), 'tasks'
|
26
24
|
end
|
@@ -29,7 +27,7 @@ class InstallRspecGenerator < RubiGen::Base
|
|
29
27
|
protected
|
30
28
|
def banner
|
31
29
|
<<-EOS
|
32
|
-
Install rspec BDD testing support.
|
30
|
+
Install rspec BDD testing support.
|
33
31
|
|
34
32
|
Includes a rake task (tasks/rspec.rake) to be loaded by the root Rakefile,
|
35
33
|
which provides a "spec" task.
|
@@ -47,11 +45,11 @@ EOS
|
|
47
45
|
# "Some comment about this option",
|
48
46
|
# "Default: none") { |x| options[:author] = x }
|
49
47
|
end
|
50
|
-
|
48
|
+
|
51
49
|
def extract_options
|
52
50
|
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
53
51
|
# Templates can access these value via the attr_reader-generated methods, but not the
|
54
52
|
# raw instance variable value.
|
55
53
|
# @author = options[:author]
|
56
54
|
end
|
57
|
-
end
|
55
|
+
end
|
File without changes
|
File without changes
|
data/{rubygems_generators/install_rspec → daemon_generators/rspec}/templates/tasks/rspec.rake
RENAMED
File without changes
|
data/lib/daemon_kit.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
# TODO: Strip this out eventually so we can run without rubygems
|
2
2
|
require 'rubygems'
|
3
3
|
|
4
|
+
require 'eventmachine'
|
5
|
+
|
4
6
|
require File.dirname(__FILE__) + '/daemon_kit/core_ext'
|
5
7
|
|
6
8
|
$:.unshift( File.dirname(__FILE__).to_absolute_path ) unless
|
7
9
|
$:.include?( File.dirname(__FILE__).to_absolute_path )
|
8
10
|
|
9
11
|
module DaemonKit
|
10
|
-
VERSION = '0.1.7.
|
12
|
+
VERSION = '0.1.7.7'
|
11
13
|
|
12
14
|
autoload :Initializer, 'daemon_kit/initializer'
|
13
15
|
autoload :Application, 'daemon_kit/application'
|
@@ -16,6 +18,8 @@ module DaemonKit
|
|
16
18
|
autoload :Safety, 'daemon_kit/safety'
|
17
19
|
autoload :PidFile, 'daemon_kit/pid_file'
|
18
20
|
autoload :AbstractLogger, 'daemon_kit/abstract_logger'
|
21
|
+
autoload :EM, 'daemon_kit/em'
|
22
|
+
autoload :Configurable, 'daemon_kit/core_ext/configurable'
|
19
23
|
|
20
24
|
autoload :Cron, 'daemon_kit/cron'
|
21
25
|
autoload :Jabber, 'daemon_kit/jabber'
|
@@ -79,7 +79,11 @@ module DaemonKit
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
@pid_file.
|
82
|
+
if @pid_file.running?
|
83
|
+
puts "Process still running, leaving pidfile behind! Consider using configuration.force_kill_wait."
|
84
|
+
else
|
85
|
+
@pid_file.cleanup
|
86
|
+
end
|
83
87
|
end
|
84
88
|
|
85
89
|
# Call this from inside a daemonized process to complete the
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module DaemonKit
|
2
|
+
|
3
|
+
# Provide some advanced helpers for managing access to instance variables.
|
4
|
+
module Configurable
|
5
|
+
|
6
|
+
def self.included(base) #:nodoc:
|
7
|
+
base.class_eval <<-EOF
|
8
|
+
@configurables = {}
|
9
|
+
@configurable_defaults = {}
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_reader :configurables, :configurable_defaults
|
13
|
+
end
|
14
|
+
EOF
|
15
|
+
|
16
|
+
base.extend( ClassMethods )
|
17
|
+
base.send( :include, InstanceMethods )
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
|
22
|
+
# Create a configurable value on any instance, which can contain
|
23
|
+
# a default value, and/or be locked.
|
24
|
+
#
|
25
|
+
# Create a standard getter/setter without a default value
|
26
|
+
#
|
27
|
+
# configurable :foo
|
28
|
+
#
|
29
|
+
# Create a getter/setter with a default value
|
30
|
+
#
|
31
|
+
# configurable :foo, true
|
32
|
+
#
|
33
|
+
# The final argument can be an options hash, which currently
|
34
|
+
# respects only one key: +locked+ (false by default). Locking a
|
35
|
+
# configurable means the value can only be set once by the
|
36
|
+
# setter method.
|
37
|
+
#
|
38
|
+
# configurable :foo, :locked => true
|
39
|
+
#
|
40
|
+
# As long as the getter method (+foo+) returns nil, the standard
|
41
|
+
# setter method will work. As soon as the getter returns a
|
42
|
+
# non-nil value the setter won't set a new value. To set a new
|
43
|
+
# value you'll have to explicitly use the #set instance method.
|
44
|
+
def configurable( name, *args )
|
45
|
+
opts = args.last.is_a?( Hash ) ? args.pop : {}
|
46
|
+
opts = { :locked => false }.merge( opts )
|
47
|
+
|
48
|
+
default = args.size <= 1 ? args.pop : args
|
49
|
+
|
50
|
+
name = name.to_sym
|
51
|
+
|
52
|
+
self.configurables[ name ] = opts
|
53
|
+
self.configurable_defaults[ name ] = default
|
54
|
+
|
55
|
+
class_eval( <<-EOF, __FILE__, __LINE__ )
|
56
|
+
def #{name} # def foo
|
57
|
+
if _configurables[:#{name}].nil? # if _configurables[:foo].nil?
|
58
|
+
self.class.configurable_defaults[:#{name}] # self.class.configurable_defaults[:foo]
|
59
|
+
else # else
|
60
|
+
_configurables[:#{name}] # _configurables[:foo]
|
61
|
+
end # end
|
62
|
+
end #
|
63
|
+
|
64
|
+
def #{name}=( value ) # def foo=( value )
|
65
|
+
if #{name}.nil? || # if foo.nil? ||
|
66
|
+
!self.class.configurables[:#{name}][:locked] # !self.class.configurables[:foo][:locked]
|
67
|
+
#
|
68
|
+
_configurables[:#{name}] = value # _configurables[:foo] = value
|
69
|
+
end # end
|
70
|
+
end # end
|
71
|
+
EOF
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
module InstanceMethods
|
77
|
+
|
78
|
+
# Force the value of a configurable to be set without any
|
79
|
+
# respect for it's locked status.
|
80
|
+
def set( name, value )
|
81
|
+
name = name.to_sym
|
82
|
+
|
83
|
+
if self.class.configurables.has_key?( name )
|
84
|
+
_configurables[ name ] = value
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def _configurables
|
91
|
+
@_configurables ||= {}
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/daemon_kit/cron.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
module DaemonKit
|
2
|
-
|
2
|
+
|
3
3
|
# Thin wrapper around rufus-scheduler gem, specifically designed to ease
|
4
4
|
# configuration of a scheduler and provide some added simplicity.
|
5
|
+
#
|
6
|
+
# For more information on rufus-scheduler, please visit the RDoc's
|
7
|
+
# at http://rufus.rubyforge.org/rufus-scheduler/
|
8
|
+
#
|
9
|
+
# To use the evented scheduler, call #DaemonKit::EM.run prior to
|
10
|
+
# setting up your first schedule.
|
5
11
|
class Cron
|
6
12
|
|
7
|
-
|
13
|
+
@instance = nil
|
8
14
|
|
9
15
|
attr_reader :scheduler
|
10
|
-
|
16
|
+
|
11
17
|
class << self
|
12
|
-
|
18
|
+
|
19
|
+
# Access to the scheduler instance
|
13
20
|
def instance
|
14
21
|
@instance ||= new
|
15
22
|
end
|
@@ -17,16 +24,19 @@ module DaemonKit
|
|
17
24
|
def scheduler
|
18
25
|
instance.scheduler
|
19
26
|
end
|
20
|
-
|
27
|
+
|
21
28
|
private :new
|
22
29
|
|
30
|
+
# Once the scheduler has been configured, call #run to block the
|
31
|
+
# current thread and keep the process alive for the scheduled
|
32
|
+
# tasks to run
|
23
33
|
def run
|
24
34
|
DaemonKit.logger.info "Starting rufus-scheduler"
|
25
35
|
|
26
|
-
|
36
|
+
if instance.is_a?( Rufus::Scheduler::PlainScheduler )
|
27
37
|
instance.scheduler.join
|
28
|
-
|
29
|
-
|
38
|
+
else
|
39
|
+
Thread.stop
|
30
40
|
end
|
31
41
|
end
|
32
42
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Based on code from Brian Takita, Yurii Rashkovskii, Ben Mabey and Aslak Hellesøy
|
3
|
+
# Adapted by Kenneth Kalmer for daemon-kit
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'test/unit/testresult'
|
7
|
+
rescue LoadError => e
|
8
|
+
e.message << "\nYou must gem install test-unit. For more info see https://rspec.lighthouseapp.com/projects/16211/tickets/292"
|
9
|
+
raise e
|
10
|
+
end
|
11
|
+
|
12
|
+
# So that Test::Unit doesn't launch at the end - makes it think it has already been run.
|
13
|
+
Test::Unit.run = true if Test::Unit.respond_to?(:run=)
|
14
|
+
|
15
|
+
$__cucumber_toplevel = self
|
16
|
+
|
17
|
+
module DaemonKit
|
18
|
+
module Cucumber
|
19
|
+
# All scenarios will execute in the context of a new instance of World.
|
20
|
+
class World
|
21
|
+
def initialize #:nodoc:
|
22
|
+
@_result = Test::Unit::TestResult.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
$__cucumber_toplevel.Before do
|
27
|
+
# Placeholder
|
28
|
+
end
|
29
|
+
|
30
|
+
$__cucumber_toplevel.After do
|
31
|
+
# Placeholder
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
World do
|
37
|
+
DaemonKit::Cucumber::World.new
|
38
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module DaemonKit
|
2
|
+
|
3
|
+
# EventMachine forms a critical part of the daemon-kit toolset, and
|
4
|
+
# especially of daemon process developers.
|
5
|
+
#
|
6
|
+
# This class abstracts away the difficulties of managing multiple
|
7
|
+
# libraries that all utilize the event reactor.
|
8
|
+
class EM
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
# Start a reactor, just like classical EM.run. If the block is
|
13
|
+
# provided, the method will block and call the provided block
|
14
|
+
# argument inside the running reactor. If the block argument is
|
15
|
+
# not provided the reactor will be started in a separate thread
|
16
|
+
# and the program will continue to run after the method. All the
|
17
|
+
# signal traps are configured to shutdown the reactor when the
|
18
|
+
# daemon exists.
|
19
|
+
def run(&block)
|
20
|
+
if ::EM.reactor_running?
|
21
|
+
DaemonKit.logger.warn "EventMachine reactor already running"
|
22
|
+
block.call if block_given?
|
23
|
+
|
24
|
+
else
|
25
|
+
if block_given?
|
26
|
+
::EM.run { block.call }
|
27
|
+
else
|
28
|
+
Thread.main[:_dk_reactor] = Thread.new { EM.run {} }
|
29
|
+
DaemonKit.trap( 'INT' ) { DaemonKit::EM.stop }
|
30
|
+
DaemonKit.trap( 'TERM' ) { DaemonKit::EM.stop }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Stop the reactor
|
36
|
+
def stop
|
37
|
+
::EM.stop_event_loop if ::EM.reactor_running?
|
38
|
+
Thread.main[:_dk_reactor].join
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -61,6 +61,10 @@ module DaemonKit
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def self.shutdown
|
64
|
+
DaemonKit.logger.info "Running shutdown hooks"
|
65
|
+
|
66
|
+
log_exceptions if DaemonKit.configuration.backtraces
|
67
|
+
|
64
68
|
DaemonKit.logger.warn "Shutting down #{DaemonKit.configuration.daemon_name}"
|
65
69
|
exit
|
66
70
|
end
|
@@ -85,6 +89,7 @@ module DaemonKit
|
|
85
89
|
|
86
90
|
include_core_lib
|
87
91
|
load_postdaemonize_configs
|
92
|
+
configure_backtraces
|
88
93
|
|
89
94
|
set_process_name
|
90
95
|
|
@@ -160,6 +165,7 @@ module DaemonKit
|
|
160
165
|
term_proc = Proc.new { DaemonKit::Initializer.shutdown }
|
161
166
|
configuration.trap( 'INT', term_proc )
|
162
167
|
configuration.trap( 'TERM', term_proc )
|
168
|
+
at_exit { DaemonKit::Initializer.shutdown }
|
163
169
|
end
|
164
170
|
|
165
171
|
def include_core_lib
|
@@ -168,13 +174,45 @@ module DaemonKit
|
|
168
174
|
end
|
169
175
|
end
|
170
176
|
|
177
|
+
def configure_backtraces
|
178
|
+
Thread.abort_on_exception = configuration.backtraces
|
179
|
+
end
|
180
|
+
|
171
181
|
def set_process_name
|
172
182
|
$0 = configuration.daemon_name
|
173
183
|
end
|
184
|
+
|
185
|
+
def self.log_exceptions
|
186
|
+
trace_file = File.join( DaemonKit.root, "backtrace-#{Time.now.strftime('%Y%m%d%H%M%S')}-#{Process.pid}.log" )
|
187
|
+
trace_log = Logger.new( trace_file )
|
188
|
+
|
189
|
+
# Find the last exception
|
190
|
+
e = nil
|
191
|
+
ObjectSpace.each_object {|o|
|
192
|
+
if ::Exception === o
|
193
|
+
e = o
|
194
|
+
end
|
195
|
+
}
|
196
|
+
|
197
|
+
trace_log.info "*** Below you'll find the most recent exception thrown, this will likely (but not certainly) be the exception that made #{DaemonKit.configuration.daemon_name} exit abnormally ***"
|
198
|
+
trace_log.error e
|
199
|
+
|
200
|
+
trace_log.info "*** Below you'll find all the exception objects in memory, some of them may have been thrown in your application, others may just be in memory because they are standard exceptions ***"
|
201
|
+
ObjectSpace.each_object {|o|
|
202
|
+
if ::Exception === o
|
203
|
+
trace_log.error o
|
204
|
+
end
|
205
|
+
}
|
206
|
+
|
207
|
+
trace_log.close
|
208
|
+
end
|
174
209
|
end
|
175
210
|
|
176
211
|
# Holds our various configuration values
|
177
212
|
class Configuration
|
213
|
+
|
214
|
+
include Configurable
|
215
|
+
|
178
216
|
# Root to the daemon
|
179
217
|
attr_reader :root_path
|
180
218
|
|
@@ -188,7 +226,7 @@ module DaemonKit
|
|
188
226
|
attr_accessor :log_level
|
189
227
|
|
190
228
|
# Path to the log file, defaults to 'log/<environment>.log'
|
191
|
-
|
229
|
+
configurable :log_path
|
192
230
|
|
193
231
|
# Duplicate log data to stdout
|
194
232
|
attr_accessor :log_stdout
|
@@ -197,10 +235,13 @@ module DaemonKit
|
|
197
235
|
attr_accessor :pid_file
|
198
236
|
|
199
237
|
# The application name
|
200
|
-
|
238
|
+
configurable :daemon_name, :locked => true
|
201
239
|
|
202
240
|
# Use the force kill patch? Give the number of seconds
|
203
|
-
|
241
|
+
configurable :force_kill_wait
|
242
|
+
|
243
|
+
# Should be log backtraces
|
244
|
+
configurable :backtraces, false
|
204
245
|
|
205
246
|
# Collection of signal traps
|
206
247
|
attr_reader :signal_traps
|
@@ -87,7 +87,7 @@ namespace :daemon_kit do
|
|
87
87
|
namespace :upgrade do
|
88
88
|
# Upgrade the initializers
|
89
89
|
task :initializers do
|
90
|
-
copy_framework_template( 'config
|
90
|
+
copy_framework_template( 'config', 'boot.rb' )
|
91
91
|
|
92
92
|
if File.directory?( File.join(DaemonKit.root, 'config', 'initializers') )
|
93
93
|
mv File.join(DaemonKit.root, 'config', 'initializers'), File.join(DAEMON_ROOT, 'config', 'pre-daemonize')
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
class FooConfig
|
4
|
+
include DaemonKit::Configurable
|
5
|
+
|
6
|
+
configurable :has_default, true
|
7
|
+
configurable :no_default
|
8
|
+
configurable :has_lock, :locked => true
|
9
|
+
end
|
10
|
+
|
11
|
+
describe DaemonKit::Configurable do
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
@foo = FooConfig.new
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should support default values" do
|
18
|
+
lambda {
|
19
|
+
@foo.has_default.should be_true
|
20
|
+
}.should_not raise_error( NoMethodError )
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should support overwriting unlocked defaults" do
|
24
|
+
lambda {
|
25
|
+
@foo.has_default = false
|
26
|
+
@foo.has_default.should be_false
|
27
|
+
}.should_not raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should support no default values" do
|
31
|
+
lambda {
|
32
|
+
@foo.no_default.should be_nil
|
33
|
+
}.should_not raise_error( NoMethodError )
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should allow setting locked values once" do
|
37
|
+
lambda {
|
38
|
+
@foo.has_lock = 1
|
39
|
+
@foo.has_lock.should == 1
|
40
|
+
|
41
|
+
@foo.has_lock = 2
|
42
|
+
@foo.has_lock.should == 1
|
43
|
+
}.should_not raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should allow bypassing the lock explicitly" do
|
47
|
+
lambda {
|
48
|
+
@foo.has_lock = 1
|
49
|
+
@foo.has_lock.should == 1
|
50
|
+
|
51
|
+
@foo.set(:has_lock, 2)
|
52
|
+
@foo.has_lock.should == 2
|
53
|
+
}.should_not raise_error
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kennethkalmer-daemon-kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.7.
|
4
|
+
version: 0.1.7.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenneth Kalmer
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-06-
|
12
|
+
date: 2009-06-22 00:00:00 -07:00
|
13
13
|
default_executable: daemon_kit
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,6 +22,16 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: 1.5.2
|
24
24
|
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: eventmachine
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.12.8
|
34
|
+
version:
|
25
35
|
- !ruby/object:Gem::Dependency
|
26
36
|
name: newgem
|
27
37
|
type: :development
|
@@ -96,6 +106,12 @@ files:
|
|
96
106
|
- daemon_generators/cron/cron_generator.rb
|
97
107
|
- daemon_generators/cron/templates/config/initializers/cron.rb
|
98
108
|
- daemon_generators/cron/templates/libexec/daemon.rb
|
109
|
+
- daemon_generators/cucumber/USAGE
|
110
|
+
- daemon_generators/cucumber/cucumber_generator.rb
|
111
|
+
- daemon_generators/cucumber/templates/cucumber
|
112
|
+
- daemon_generators/cucumber/templates/cucumber.rake
|
113
|
+
- daemon_generators/cucumber/templates/cucumber_environment.rb
|
114
|
+
- daemon_generators/cucumber/templates/env.rb
|
99
115
|
- daemon_generators/deploy_capistrano/deploy_capistrano_generator.rb
|
100
116
|
- daemon_generators/deploy_capistrano/templates/Capfile
|
101
117
|
- daemon_generators/deploy_capistrano/templates/USAGE
|
@@ -114,6 +130,12 @@ files:
|
|
114
130
|
- daemon_generators/nanite_agent/templates/config/nanite.yml
|
115
131
|
- daemon_generators/nanite_agent/templates/lib/actors/sample.rb
|
116
132
|
- daemon_generators/nanite_agent/templates/libexec/daemon.rb
|
133
|
+
- daemon_generators/rspec/USAGE
|
134
|
+
- daemon_generators/rspec/rspec_generator.rb
|
135
|
+
- daemon_generators/rspec/templates/spec.rb
|
136
|
+
- daemon_generators/rspec/templates/spec/spec.opts
|
137
|
+
- daemon_generators/rspec/templates/spec/spec_helper.rb
|
138
|
+
- daemon_generators/rspec/templates/tasks/rspec.rake
|
117
139
|
- lib/daemon_kit.rb
|
118
140
|
- lib/daemon_kit/abstract_logger.rb
|
119
141
|
- lib/daemon_kit/amqp.rb
|
@@ -123,9 +145,12 @@ files:
|
|
123
145
|
- lib/daemon_kit/config.rb
|
124
146
|
- lib/daemon_kit/console_daemon.rb
|
125
147
|
- lib/daemon_kit/core_ext.rb
|
148
|
+
- lib/daemon_kit/core_ext/configurable.rb
|
126
149
|
- lib/daemon_kit/core_ext/string.rb
|
127
150
|
- lib/daemon_kit/cron.rb
|
151
|
+
- lib/daemon_kit/cucumber/world.rb
|
128
152
|
- lib/daemon_kit/deployment/capistrano.rb
|
153
|
+
- lib/daemon_kit/em.rb
|
129
154
|
- lib/daemon_kit/error_handlers/base.rb
|
130
155
|
- lib/daemon_kit/error_handlers/hoptoad.rb
|
131
156
|
- lib/daemon_kit/error_handlers/mail.rb
|
@@ -141,12 +166,6 @@ files:
|
|
141
166
|
- lib/daemon_kit/tasks/god.rake
|
142
167
|
- lib/daemon_kit/tasks/log.rake
|
143
168
|
- lib/daemon_kit/tasks/monit.rake
|
144
|
-
- rubygems_generators/install_rspec/USAGE
|
145
|
-
- rubygems_generators/install_rspec/install_rspec_generator.rb
|
146
|
-
- rubygems_generators/install_rspec/templates/spec.rb
|
147
|
-
- rubygems_generators/install_rspec/templates/spec/spec.opts
|
148
|
-
- rubygems_generators/install_rspec/templates/spec/spec_helper.rb
|
149
|
-
- rubygems_generators/install_rspec/templates/tasks/rspec.rake
|
150
169
|
- script/console
|
151
170
|
- script/destroy
|
152
171
|
- script/generate
|
@@ -154,6 +173,7 @@ files:
|
|
154
173
|
- spec/abstract_logger_spec.rb
|
155
174
|
- spec/argument_spec.rb
|
156
175
|
- spec/config_spec.rb
|
176
|
+
- spec/configurable_spec.rb
|
157
177
|
- spec/daemon_kit_spec.rb
|
158
178
|
- spec/error_handlers_spec.rb
|
159
179
|
- spec/fixtures/env.yml
|
@@ -236,11 +256,11 @@ specification_version: 2
|
|
236
256
|
summary: Daemon Kit aims to simplify creating Ruby daemons by providing a sound application skeleton (through a generator), task specific generators (jabber bot, etc) and robust environment management code.
|
237
257
|
test_files:
|
238
258
|
- test/test_generator_helper.rb
|
239
|
-
- test/test_jabber_generator.rb
|
240
259
|
- test/test_cron_generator.rb
|
241
|
-
- test/test_amqp_generator.rb
|
242
260
|
- test/test_nanite_agent_generator.rb
|
243
261
|
- test/test_daemon_kit_config.rb
|
244
262
|
- test/test_helper.rb
|
263
|
+
- test/test_amqp_generator.rb
|
245
264
|
- test/test_daemon-kit_generator.rb
|
246
265
|
- test/test_deploy_capistrano_generator.rb
|
266
|
+
- test/test_jabber_generator.rb
|