daemon-kit 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/History.txt +17 -0
  2. data/Manifest.txt +62 -0
  3. data/PostInstall.txt +6 -0
  4. data/README.textile +94 -0
  5. data/Rakefile +31 -0
  6. data/TODO.txt +24 -0
  7. data/app_generators/daemon_kit/USAGE +7 -0
  8. data/app_generators/daemon_kit/daemon_kit_generator.rb +120 -0
  9. data/app_generators/daemon_kit/templates/README +48 -0
  10. data/app_generators/daemon_kit/templates/Rakefile +4 -0
  11. data/app_generators/daemon_kit/templates/bin/daemon.erb +7 -0
  12. data/app_generators/daemon_kit/templates/config/boot.rb +68 -0
  13. data/app_generators/daemon_kit/templates/config/environment.rb +19 -0
  14. data/app_generators/daemon_kit/templates/config/environments/development.rb +0 -0
  15. data/app_generators/daemon_kit/templates/config/environments/production.rb +0 -0
  16. data/app_generators/daemon_kit/templates/config/environments/test.rb +0 -0
  17. data/app_generators/daemon_kit/templates/config/initializers/readme +11 -0
  18. data/app_generators/daemon_kit/templates/libexec/daemon.erb +18 -0
  19. data/bin/daemon_kit +19 -0
  20. data/daemon_generators/amqp/USAGE +5 -0
  21. data/daemon_generators/amqp/amqp_generator.rb +65 -0
  22. data/daemon_generators/amqp/templates/config/amqp.yml +28 -0
  23. data/daemon_generators/amqp/templates/config/initializers/amqp.rb +7 -0
  24. data/daemon_generators/amqp/templates/libexec/daemon.rb +29 -0
  25. data/daemon_generators/cron/USAGE +5 -0
  26. data/daemon_generators/cron/cron_generator.rb +64 -0
  27. data/daemon_generators/cron/templates/config/initializers/cron.rb +7 -0
  28. data/daemon_generators/cron/templates/libexec/daemon.rb +39 -0
  29. data/daemon_generators/jabber/USAGE +5 -0
  30. data/daemon_generators/jabber/jabber_generator.rb +65 -0
  31. data/daemon_generators/jabber/templates/config/initializers/jabber.rb +7 -0
  32. data/daemon_generators/jabber/templates/config/jabber.yml +26 -0
  33. data/daemon_generators/jabber/templates/libexec/daemon.rb +27 -0
  34. data/lib/daemon_kit.rb +14 -0
  35. data/lib/daemon_kit/amqp.rb +41 -0
  36. data/lib/daemon_kit/application.rb +34 -0
  37. data/lib/daemon_kit/cron.rb +38 -0
  38. data/lib/daemon_kit/initializer.rb +255 -0
  39. data/lib/daemon_kit/jabber.rb +172 -0
  40. data/lib/daemon_kit/patches/force_kill_wait.rb +120 -0
  41. data/lib/daemon_kit/tasks.rb +2 -0
  42. data/lib/daemon_kit/tasks/framework.rake +75 -0
  43. data/rubygems_generators/install_rspec/USAGE +5 -0
  44. data/rubygems_generators/install_rspec/install_rspec_generator.rb +57 -0
  45. data/rubygems_generators/install_rspec/templates/spec.rb +11 -0
  46. data/rubygems_generators/install_rspec/templates/spec/spec.opts +1 -0
  47. data/rubygems_generators/install_rspec/templates/spec/spec_helper.rb +10 -0
  48. data/rubygems_generators/install_rspec/templates/tasks/rspec.rake +21 -0
  49. data/script/console +10 -0
  50. data/script/destroy +14 -0
  51. data/script/generate +14 -0
  52. data/script/txt2html +71 -0
  53. data/spec/daemon_kit_spec.rb +7 -0
  54. data/spec/initializer_spec.rb +31 -0
  55. data/spec/spec.opts +1 -0
  56. data/spec/spec_helper.rb +30 -0
  57. data/tasks/rspec.rake +21 -0
  58. data/test/test_amqp_generator.rb +48 -0
  59. data/test/test_cron_generator.rb +45 -0
  60. data/test/test_daemon-kit_generator.rb +67 -0
  61. data/test/test_generator_helper.rb +29 -0
  62. data/test/test_jabber_generator.rb +49 -0
  63. 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,2 @@
1
+ # Load all the take tasks in the gem
2
+ Dir[File.join(File.dirname(__FILE__), '**/*.rake')].each { |rake| load rake }
@@ -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,5 @@
1
+ Description:
2
+
3
+
4
+ Usage:
5
+
@@ -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,11 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ # Time to add your specs!
4
+ # http://rspec.info/
5
+ describe "Place your specs here" do
6
+
7
+ it "find this spec in spec directory" do
8
+ violated "Be sure to write your specs"
9
+ end
10
+
11
+ end
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ require File.dirname(__FILE__) + '/../config/boot'
10
+ require '<%= gem_name %>'
@@ -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,7 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe DaemonKit do
4
+
5
+ it "should work"
6
+
7
+ end
@@ -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