diff --git a/README.rdoc b/README.rdoc index 4f8a317..2e82d13 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,10 +1,10 @@ -= djinn += Djinn Djinn is a very basic helper for building simple daemons. == Non-Rails Example -#!/usr/bin/env ruby + #!/usr/bin/env ruby require 'rubygems' require 'djinn' @@ -45,17 +45,24 @@ Assuming you didn't sleep there your script would end and the daemon would detach and run in the background until it dies or gets killed. You can wrap argument parsing around that if you want, or do it in any other way. By default the daemon will look for a config YAML file in same directory as you executed it -from, name the same as the djinn class, so in this case "basic.yml". It will by +from, named the same as the Djinn class, so in this case "basic.yml". It will by default create the pid and log files in the same way. You can change this by putting it in the config file or supplying an options hash: - { + options = { 'pid_file_path' => 'path/to/pid/file', 'log_file_path' => 'path/to/log/file' } -It's ugly, but the solution is minimal, and so flexible I think. The rails daemon -helpers include some option parsing and so forth and do a little more for you. + djinn.start(options) + +These options will also be passed to your *perform* method, so you can include +anything you need in the hash as well, or in the YAML file for that matter. + +It might seem ugly, but the solution is minimal, and so remains flexible I think. +The rails daemon helpers are an implementation on top of this illustrating how it +can be tailored to include some option parsing and so forth, and so do a little +more for you. == Rails Example diff --git a/Rakefile b/Rakefile index abcafee..03eb43b 100644 --- a/Rakefile +++ b/Rakefile @@ -13,9 +13,14 @@ begin gem.add_development_dependency "shoulda", ">= 2.11.1" gem.files.exclude 'example/**/*' gem.test_files.exclude 'example/**/*' + gem.has_rdoc = true + gem.rubyforge_project = 'djinn' # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings end Jeweler::GemcutterTasks.new + Jeweler::RubyforgeTasks.new do |rubyforge| + rubyforge.doc_task = "rdoc" + end rescue LoadError puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" end diff --git a/lib/djinn.rb b/lib/djinn.rb index ca0bd41..437f1e5 100644 --- a/lib/djinn.rb +++ b/lib/djinn.rb @@ -1,5 +1,7 @@ require 'djinn/base' +# This is a base implementation which handles looking for config +# files and sets up the default locations for pid and log files module Djinn include Djinn::Base diff --git a/lib/djinn/base.rb b/lib/djinn/base.rb index ca95d91..ffafd9f 100644 --- a/lib/djinn/base.rb +++ b/lib/djinn/base.rb @@ -5,6 +5,7 @@ require 'logging' module Djinn + # The base class from which all Djinn spring forth module Base include Djinn::Tonic @@ -12,8 +13,9 @@ module Base attr_reader :config + # Base implementation does nothing worthwhile, you should override this + # in your own implementation def perform config={} - # base implementation does nothing worthwhile trap('TERM') { handle_exit } trap('INT') { handle_exit } while true @@ -22,11 +24,13 @@ def perform config={} end end + # Override this with useful exit code if you need to, but remember to + # call *super* or call *exit* yourself, or your Djinn will be immortal def handle_exit - # override this with useful exit code if you need it exit(0) end + # Starts the Djinn in the background def start config={} @config = (config.empty?) ? load_config : config.empty? log "Starting #{name} in the background.." @@ -38,6 +42,8 @@ def start config={} end end + # Starts the Djinn in the foreground, which is often useful for + # testing or other noble pursuits def run config={} @config = (config.empty?) ? load_config : config.empty? log "Starting #{name} in the foreground.." @@ -46,11 +52,14 @@ def run config={} perform(config) end + # Convenience method, really just calls *stop* and then *start* for you :P def restart config={} stop start(config) end + # Stops the Djinn, unless you change the location of the pid file, in + # which case its all about you and the *kill* command def stop config={} @config = (config.empty?) ? load_config : config.empty? pidfile = get_pidfile(@config) @@ -67,12 +76,15 @@ def stop config={} protected + # The name used to identify the Djinn, for pid and log file + # naming, as well as finding default config files def name underscore(self.class.name) end private + # Shamelessly stolen from the Rails source def underscore(camel_cased_word) camel_cased_word.to_s.gsub(/::/, '/'). gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').