Skip to content
Browse files

daemon-kit skeleton

  • Loading branch information...
0 parents commit 6b6a343e71647ec949275af651682378d482bb74 unknown committed Jul 6, 2010
48 README
@@ -0,0 +1,48 @@
+DaemonKit README
+================
+
+DaemonKit has generated a skeleton Ruby daemon for you to build on. Please read
+through this file to ensure you get going quickly.
+
+Directories
+===========
+
+bin/
+ bunnicula - Stub executable to control your daemon with
+
+config/
+ Environment configuration files
+
+lib/
+ Place for your libraries
+
+libexec/
+ bunnicula.rb - Your daemon code
+
+log/
+ Log files based on the environment name
+
+spec/
+ rspec's home
+
+tasks/
+ Place for rake tasks
+
+vendor/
+ Place for unpacked gems and DaemonKit
+
+tmp/
+ Scratch folder
+
+
+Logging
+=======
+
+One of the biggest issues with writing daemons are gettign insight into what your
+daemons are doing. Logging with DaemonKit is simplified as DaemonKit creates log
+files per environment in log.
+
+On all environments except production the log level is set to DEBUG, but you can
+toggle the log level by sending the running daemon SIGUSR1 and SIGUSR2 signals.
+SIGUSR1 will toggle between DEBUG and INFO levels, SIGUSR2 will blatantly set the
+level to DEBUG.
6 Rakefile
@@ -0,0 +1,6 @@
+require File.dirname(__FILE__) + '/config/boot'
+
+require 'rake'
+require 'daemon_kit/tasks'
+
+Dir[File.join(File.dirname(__FILE__), 'tasks/*.rake')].each { |rake| load rake }
7 bin/bunnicula
@@ -0,0 +1,7 @@
+#!/usr/bin/env ruby
+#
+# Stub executable for bunnicula
+
+require File.dirname(__FILE__) + '/../config/environment'
+
+DaemonKit::Application.exec( DAEMON_ROOT + '/libexec/bunnicula-daemon.rb' )
28 config/amqp.yml
@@ -0,0 +1,28 @@
+# AMQP client configuration file
+
+# These values will be used to configure the ampq gem, any values
+# omitted will let the gem use it's own defaults.
+
+# The configuration specifies the following keys:
+# * user - Username for the broker
+# * pass - Password for the broker
+# * host - Hostname where the broker is running
+# * vhost - Vhost to connect to
+# * port - Port where the broker is running
+# * ssl - Use ssl or not
+# * timeout - Timeout
+
+defaults: &defaults
+ user: guest
+ pass: guest
+ host: localhost
+ vhost: /
+
+development:
+ <<: *defaults
+
+test:
+ <<: *defaults
+
+production:
+ <<: *defaults
12 config/arguments.rb
@@ -0,0 +1,12 @@
+# Argument handling for your daemon is configured here.
+#
+# You have access to two variables when this file is
+# parsed. The first is +opts+, which is the object yielded from
+# +OptionParser.new+, the second is +@options+ which is a standard
+# Ruby hash that is later accessible through
+# DaemonKit.arguments.options and can be used in your daemon process.
+
+# Here is an example:
+# opts.on('-f', '--foo FOO', 'Set foo') do |foo|
+# @options[:foo] = foo
+# end
59 config/boot.rb
@@ -0,0 +1,59 @@
+# Don't change this file!
+# Configure your daemon in config/environment.rb
+
+DAEMON_ROOT = "#{File.expand_path(File.dirname(__FILE__))}/.." unless defined?( DAEMON_ROOT )
+
+module DaemonKit
+ class << self
+ def boot!
+ unless booted?
+ pick_boot.run
+ end
+ end
+
+ def booted?
+ defined? DaemonKit::Initializer
+ end
+
+ def pick_boot
+ (vendor_kit? ? VendorBoot : GemBoot).new
+ end
+
+ def vendor_kit?
+ File.exists?( "#{DAEMON_ROOT}/vendor/daemon_kit" )
+ end
+ end
+
+ class Boot
+ def run
+ load_initializer
+ DaemonKit::Initializer.run
+ end
+ end
+
+ class VendorBoot < Boot
+ def load_initializer
+ require "#{DAEMON_ROOT}/vendor/daemon_kit/lib/daemon_kit/initializer"
+ end
+ end
+
+ class GemBoot < Boot
+ def load_initializer
+ begin
+ gem 'daemon-kit'
+ require 'daemon_kit/initializer'
+ rescue Gem::LoadError => e
+ msg = <<EOF
+You are missing the daemon-kit gem. Please install the following gems:
+
+* Stable - sudo gem install daemon-kit
+
+EOF
+ $stderr.puts msg
+ exit 1
+ end
+ end
+ end
+end
+
+DaemonKit.boot!
23 config/environment.rb
@@ -0,0 +1,23 @@
+# Be sure to restart your daemon when you modify this file
+
+# Uncomment below to force your daemon into production mode
+#ENV['DAEMON_ENV'] ||= 'production'
+
+# Boot up
+require File.join(File.dirname(__FILE__), 'boot')
+
+DaemonKit::Initializer.run do |config|
+
+ # The name of the daemon as reported by process monitoring tools
+ config.daemon_name = 'bunnicula'
+
+ # Force the daemon to be killed after X seconds from asking it to
+ # config.force_kill_wait = 30
+
+ # Log backraces when a thread/daemon dies (Recommended)
+ # config.backtraces = true
+
+ # Configure the safety net (see DaemonKit::Safety)
+ # config.safety_net.handler = :mail # (or :hoptoad )
+ # config.safety_net.mail.host = 'localhost'
+end
2 config/environments/development.rb
@@ -0,0 +1,2 @@
+# This is the same context as the environment.rb file, it is only
+# loaded afterwards and only in the development environment
5 config/environments/production.rb
@@ -0,0 +1,5 @@
+# This is the same context as the environment.rb file, it is only
+# loaded afterwards and only in the production environment
+
+# Change the production log level to debug
+#config.log_level = :debug
2 config/environments/test.rb
@@ -0,0 +1,2 @@
+# This is the same context as the environment.rb file, it is only
+# loaded afterwards and only in the test environment
7 config/initializers/bunnicula.rb
@@ -0,0 +1,7 @@
+begin
+ require 'amqp'
+ require 'mq'
+rescue LoadError
+ $stderr.puts "Missing amqp gem. Please run 'gem install amqp'."
+ exit 1
+end
5 config/post-daemonize/readme
@@ -0,0 +1,5 @@
+# You can place files in here to be loaded after the code is daemonized.
+#
+# All the files placed here will just be required into the running
+# process. This is the correct place to open any IO objects, establish
+# database connections, etc.
12 config/pre-daemonize/readme
@@ -0,0 +1,12 @@
+# You can place files in here to be loaded before the code is daemonized.
+#
+# DaemonKit looks for a file named '<config.daemon_name>.rb' and loads
+# that file first, and inside a DaemonKit::Initializer block. The
+# remaning files then simply required into the running process.
+#
+# These files are mostly useful for operations that should fail blatantly
+# before daemonizing, like loading gems.
+#
+# Be careful not to open any form of IO in here and expecting it to be
+# open inside the running daemon since all IO instances are closed when
+# daemonizing (including STDIN, STDOUT & STDERR).
2 lib/bunnicula.rb
@@ -0,0 +1,2 @@
+# Your starting point for daemon specific classes. This directory is
+# already included in your load path, so no need to specify it.
37 libexec/bunnicula-daemon.rb
@@ -0,0 +1,37 @@
+# Generated amqp daemon
+
+# Do your post daemonization configuration here
+# At minimum you need just the first line (without the block), or a lot
+# of strange things might start happening...
+DaemonKit::Application.running! do |config|
+ # Trap signals with blocks or procs
+ # config.trap( 'INT' ) do
+ # # do something clever
+ # end
+ # config.trap( 'TERM', Proc.new { puts 'Going down' } )
+end
+
+# IMPORTANT CONFIGURATION NOTE
+#
+# Please review and update 'config/amqp.yml' accordingly or this
+# daemon won't work as advertised.
+
+# Run an event-loop for processing
+DaemonKit::AMQP.run do
+ # Inside this block we're running inside the reactor setup by the
+ # amqp gem. Any code in the examples (from the gem) would work just
+ # fine here.
+
+ # Uncomment this for connection keep-alive
+ # AMQP.conn.connection_status do |status|
+ # DaemonKit.logger.debug("AMQP connection status changed: #{status}")
+ # if status == :disconnected
+ # AMQP.conn.reconnect(true)
+ # end
+ # end
+
+ amq = ::MQ.new
+ amq.queue('test').subscribe do |msg|
+ DaemonKit.logger.debug "Received message: #{msg.inspect}"
+ end
+end
3 script/console
@@ -0,0 +1,3 @@
+#!/usr/bin/env ruby
+require File.dirname(__FILE__) + '/../config/boot'
+require 'daemon_kit/commands/console'
14 script/destroy
@@ -0,0 +1,14 @@
+#!/usr/bin/env ruby
+APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+
+begin
+ require 'rubigen'
+rescue LoadError
+ require 'rubygems'
+ require 'rubigen'
+end
+require 'rubigen/scripts/destroy'
+
+ARGV.shift if ['--help', '-h'].include?(ARGV[0])
+RubiGen::Base.use_component_sources! [:daemon, :test_unit]
+RubiGen::Scripts::Destroy.new.run(ARGV)
14 script/generate
@@ -0,0 +1,14 @@
+#!/usr/bin/env ruby
+APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+
+begin
+ require 'rubigen'
+rescue LoadError
+ require 'rubygems'
+ require 'rubigen'
+end
+require 'rubigen/scripts/generate'
+
+ARGV.shift if ['--help', '-h'].include?(ARGV[0])
+RubiGen::Base.use_component_sources! [:daemon]
+RubiGen::Scripts::Generate.new.run(ARGV)
11 spec/bunnicula_spec.rb
@@ -0,0 +1,11 @@
+require File.dirname(__FILE__) + '/spec_helper.rb'
+
+# Time to add your specs!
+# http://rspec.info/
+describe "Place your specs here" do
+
+ it "find this spec in spec directory" do
+ violated "Be sure to write your specs"
+ end
+
+end
1 spec/spec.opts
@@ -0,0 +1 @@
+--colour
23 spec/spec_helper.rb
@@ -0,0 +1,23 @@
+DAEMON_ENV = 'test' unless defined?( DAEMON_ENV )
+
+begin
+ require 'spec'
+rescue LoadError
+ require 'rubygems'
+ gem 'rspec'
+ require 'spec'
+end
+
+require File.dirname(__FILE__) + '/../config/environment'
+DaemonKit::Application.running!
+
+Spec::Runner.configure do |config|
+ # == Mock Framework
+ #
+ # RSpec uses it's own mocking framework by default. If you prefer to
+ # use mocha, flexmock or RR, uncomment the appropriate line:
+ #
+ # config.mock_with :mocha
+ # config.mock_with :flexmock
+ # config.mock_with :rr
+end
19 tasks/rspec.rake
@@ -0,0 +1,19 @@
+begin
+ require 'spec'
+ require 'spec/rake/spectask'
+rescue LoadError
+ puts <<-EOS
+To use rspec for testing you must install rspec gem:
+ gem install rspec
+EOS
+end
+
+begin
+ desc "Run the specs under spec/"
+ Spec::Rake::SpecTask.new do |t|
+ t.spec_opts = ['--options', "spec/spec.opts"]
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ end
+rescue NameError
+ # No loss, warning printed already
+end

0 comments on commit 6b6a343

Please sign in to comment.
Something went wrong with that request. Please try again.