mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Initial creation of the Configurator config system.
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@118 19e92222-5c0b-0410-8929-a290d50e31e9
This commit is contained in:
parent
6634d89019
commit
6511a0a013
1 changed files with 212 additions and 0 deletions
212
lib/mongrel.rb
212
lib/mongrel.rb
|
@ -7,6 +7,7 @@ require 'mongrel/handlers'
|
|||
require 'mongrel/command'
|
||||
require 'timeout'
|
||||
require 'mongrel/tcphack'
|
||||
require 'yaml'
|
||||
|
||||
|
||||
# Mongrel module containing all of the classes (include C extensions) for running
|
||||
|
@ -455,4 +456,215 @@ module Mongrel
|
|||
|
||||
end
|
||||
|
||||
|
||||
# Implements a simple DSL for configuring a Mongrel server for your
|
||||
# purposes. More used by framework implementers to setup Mongrel
|
||||
# how they like, but could be used by regular folks to add more things
|
||||
# to an existing mongrel configuration.
|
||||
#
|
||||
# It is used like this:
|
||||
#
|
||||
# require 'mongrel'
|
||||
# config = Mongrel::Configurator.new :host => "127.0.0.1" do
|
||||
# listener :port => 3000 do
|
||||
# uri "/app", :handler => Mongrel::DirHandler.new(".", load_mime_map("mime.yaml"))
|
||||
# end
|
||||
# run
|
||||
# end
|
||||
#
|
||||
# This will setup a simple DirHandler at the current directory and load additional
|
||||
# mime types from mimy.yaml. The :host => "127.0.0.1" is actually not
|
||||
# specific to the servers but just a hash of default parameters that all
|
||||
# server or uri calls receive.
|
||||
#
|
||||
# When you are inside the block after Mongrel::Configurator.new you can simply
|
||||
# call functions that are part of Configurator (like server, uri, daemonize, etc)
|
||||
# without having to refer to anything else. You can also call these functions on
|
||||
# the resulting object directly for additional configuration.
|
||||
#
|
||||
# A major thing about Configurator is that it actually lets you configure
|
||||
# multiple listeners for any hosts and ports you want. These are kept in a
|
||||
# map config.listeners so you can get to them.
|
||||
class Configurator
|
||||
attr_reader :listeners
|
||||
attr_reader :defaults
|
||||
|
||||
# You pass in initial defaults and then a block to continue configuring.
|
||||
def initialize(defaults={}, &blk)
|
||||
@listeners = {}
|
||||
@defaults = defaults
|
||||
|
||||
if blk
|
||||
cloaker(&blk).bind(self).call
|
||||
end
|
||||
end
|
||||
|
||||
# Do not call this. You were warned.
|
||||
def cloaker &blk
|
||||
(class << self; self; end).class_eval do
|
||||
define_method :cloaker_, &blk
|
||||
meth = instance_method( :cloaker_ )
|
||||
remove_method :cloaker_
|
||||
meth
|
||||
end
|
||||
end
|
||||
|
||||
# This will resolve the given options against the defaults.
|
||||
# Normally just used internally.
|
||||
def resolve_defaults(options)
|
||||
options.merge(@defaults)
|
||||
end
|
||||
|
||||
# Starts a listener block. This is the only one that actually takes
|
||||
# a block and then you make Configurator.uri calls in order to setup
|
||||
# your URIs and handlers. If you write your Handlers as GemPlugins
|
||||
# then you can use load_plugins and plugin to load them.
|
||||
#
|
||||
# It expects the following options (or defaults):
|
||||
#
|
||||
# * :host => Host name to bind.
|
||||
# * :port => Port to bind.
|
||||
#
|
||||
def listener(options={},&blk)
|
||||
ops = resolve_defaults(options)
|
||||
|
||||
@listener = Mongrel::HttpServer.new(ops[:host], ops[:port].to_i)
|
||||
@listener_name = "#{ops[:host]}:#{ops[:port]}"
|
||||
@listeners[@listener_name] = @listener
|
||||
|
||||
if blk
|
||||
cloaker(&blk).bind(self).call
|
||||
end
|
||||
|
||||
# all done processing this listener setup
|
||||
@listener = nil
|
||||
@listener_name = nil
|
||||
end
|
||||
|
||||
|
||||
# Called inside a Configurator.listener block in order to
|
||||
# add URI->handler mappings for that listener. Use this as
|
||||
# many times as you like. It expects the following options
|
||||
# or defaults:
|
||||
#
|
||||
# * :handler => Handler to use for this location.
|
||||
def uri(location, options={})
|
||||
ops = resolve_defaults(options)
|
||||
@listener.register(location, ops[:handler])
|
||||
end
|
||||
|
||||
|
||||
# Daemonizes the current Ruby script turning all the
|
||||
# listeners into an actual "server" or detached process.
|
||||
# You must call this *before* frameworks that open files
|
||||
# as otherwise the files will be closed by this function.
|
||||
#
|
||||
# Does not work for Win32 systems (the call is silently ignored).
|
||||
#
|
||||
# Requires the following options or defaults:
|
||||
#
|
||||
# * :cwd => Directory to change to.
|
||||
# * :log_file => Where to write STDOUT and STDERR.
|
||||
# * :pid_file => Where to write the process ID.
|
||||
#
|
||||
def daemonize(options={})
|
||||
# save this for later since daemonize will hose it
|
||||
if RUBY_PLATFORM !~ /mswin/
|
||||
require 'daemons/daemonize'
|
||||
|
||||
Daemonize.daemonize(log_file=File.join(options[:cwd], options[:log_file]))
|
||||
|
||||
# change back to the original starting directory
|
||||
Dir.chdir(options[:cwd])
|
||||
|
||||
open(options[:pid_file],"w") {|f| f.write(Process.pid) }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Uses the GemPlugin system to easily load plugins based on their
|
||||
# gem dependencies. You pass in either an :includes => [] or
|
||||
# :excludes => [] setting listing the names of plugins to include
|
||||
# or exclude from the loading.
|
||||
def load_plugins(options={})
|
||||
|
||||
load_settings = {}
|
||||
if options[:includes]
|
||||
options[:includes].each do |plugin|
|
||||
load_settings[plugin] = GemPlugin::INCLUDE
|
||||
end
|
||||
end
|
||||
|
||||
if options[:excludes]
|
||||
options[:excludes].each do |plugin|
|
||||
load_settings[plugin] = GemPlugin::EXCLUDE
|
||||
end
|
||||
end
|
||||
|
||||
GemPlugin::Manager.instance.load(load_settings)
|
||||
end
|
||||
|
||||
|
||||
# Easy way to load a YAML file and apply default settings.
|
||||
def load_yaml(file, default={})
|
||||
default.merge(YAML.load_file(file))
|
||||
end
|
||||
|
||||
|
||||
# Loads the MIME map file and checks that it is correct
|
||||
# on loading. This is commonly passed to Mongrel::DirHandler
|
||||
# or any framework handler that uses DirHandler to serve files.
|
||||
# You can also include a set of default MIME types as additional
|
||||
# settings. See Mongrel::DirHandler for how the MIME types map
|
||||
# is organized.
|
||||
def load_mime_map(file, mime={})
|
||||
# configure any requested mime map
|
||||
STDERR.puts "Loading additional MIME types from #{file}"
|
||||
mime = load_yaml(file, mime)
|
||||
|
||||
# check all the mime types to make sure they are the right format
|
||||
mime.each {|k,v| STDERR.puts "WARNING: MIME type #{k} must start with '.'" if k.index(".") != 0 }
|
||||
|
||||
return mime
|
||||
end
|
||||
|
||||
|
||||
# Loads and creates a plugin for you based on the given
|
||||
# name and configured with the selected options. The options
|
||||
# are merged with the defaults prior to passing them in.
|
||||
def plugin(name, options={})
|
||||
ops = resolve_defaults(options)
|
||||
GemPlugin::Manager.instance.create(plugin, ops)
|
||||
end
|
||||
|
||||
|
||||
# Works like a meta run method which goes through all the
|
||||
# configured listeners. Use the Configurator.join method
|
||||
# to prevent Ruby from exiting until each one is done.
|
||||
def run
|
||||
@listeners.each {|name,s|
|
||||
STDERR.puts "Running #{name} listener."
|
||||
s.run
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
# Calls .stop on all the configured listeners so they
|
||||
# stop processing requests (gracefully).
|
||||
def stop
|
||||
@listeners.each {|name,s|
|
||||
STDERR.puts "Stopping #{name} listener."
|
||||
s.stop
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
# This method should actually be called *outside* of the
|
||||
# Configurator block so that you can control it. In otherwords
|
||||
# do it like: config.join.
|
||||
def join
|
||||
@listeners.values.each {|s| s.acceptor.join }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue