⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 configurator.rb

📁 Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 经过两年开发后
💻 RB
字号:
require 'yaml'require 'etc'module Mongrel  # 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.  #  # * :pid_file => Where to write the process ID.  class Configurator    attr_reader :listeners    attr_reader :defaults    attr_reader :needs_restart    # You pass in initial defaults and then a block to continue configuring.    def initialize(defaults={}, &blk)      @listener = nil      @listener_name = nil      @listeners = {}      @defaults = defaults      @needs_restart = false      @pid_file = defaults[:pid_file]      if blk        cloaker(&blk).bind(self).call      end    end    # Change privilege of the process to specified user and group.    def change_privilege(user, group)      begin        if group          log "Changing group to #{group}."          Process::GID.change_privilege(Etc.getgrnam(group).gid)        end        if user          log "Changing user to #{user}."           Process::UID.change_privilege(Etc.getpwnam(user).uid)        end      rescue Errno::EPERM        log "FAILED to change user:group #{user}:#{group}: #$!"        exit 1      end    end    def remove_pid_file      File.unlink(@pid_file) if @pid_file and File.exists?(@pid_file)    end    # Writes the PID file but only if we're on windows.    def write_pid_file      if RUBY_PLATFORM !~ /mswin/        log "Writing PID file to #{@pid_file}"        open(@pid_file,"w") {|f| f.write(Process.pid) }      end    end    # generates a class for cloaking the current self and making the DSL nicer    def cloaking_class      class << self        self      end    end    # Do not call this.  You were warned.    def cloaker(&blk)      cloaking_class.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.    # * :num_processors => The maximum number of concurrent threads allowed.  (950 default)    # * :timeout => 1/100th of a second timeout between requests. (10 is 1/10th, 0 is timeout)    # * :user => User to change to, must have :group as well.    # * :group => Group to change to, must have :user as well.    #    def listener(options={},&blk)      raise "Cannot call listener inside another listener block." if (@listener or @listener_name)      ops = resolve_defaults(options)      ops[:num_processors] ||= 950      ops[:timeout] ||= 0      @listener = Mongrel::HttpServer.new(ops[:host], ops[:port].to_i, ops[:num_processors].to_i, ops[:timeout].to_i)      @listener_name = "#{ops[:host]}:#{ops[:port]}"      @listeners[@listener_name] = @listener      if ops[:user] and ops[:group]        change_privilege(ops[:user], ops[:group])      end      # Does the actual cloaking operation to give the new implicit self.      if blk        cloaker(&blk).bind(self).call      end      # all done processing this listener setup, reset implicit variables      @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 => HttpHandler -- Handler to use for this location.    # * :in_front => true/false -- Rather than appending, it prepends this handler.    def uri(location, options={})      ops = resolve_defaults(options)      @listener.register(location, ops[:handler], ops[:in_front])    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.    #     # It is safe to call this on win32 as it will only require the daemons    # gem/library if NOT win32.    def daemonize(options={})      ops = resolve_defaults(options)      # save this for later since daemonize will hose it      if RUBY_PLATFORM !~ /mswin/        require 'daemons/daemonize'        logfile = ops[:log_file]        if logfile[0].chr != "/"          logfile = File.join(ops[:cwd],logfile)          if not File.exist?(File.dirname(logfile))            log "!!! Log file directory not found at full path #{File.dirname(logfile)}.  Update your configuration to use a full path."            exit 1          end        end        Daemonize.daemonize(logfile)        # change back to the original starting directory        Dir.chdir(ops[:cwd])      else        log "WARNING: Win32 does not support daemon mode."      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 when determining the dependencies.    def load_plugins(options={})      ops = resolve_defaults(options)      load_settings = {}      if ops[:includes]        ops[:includes].each do |plugin|          load_settings[plugin] = GemPlugin::INCLUDE        end      end      if ops[:excludes]        ops[: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      mime = load_yaml(file, mime)      # check all the mime types to make sure they are the right format      mime.each {|k,v| log "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(name, ops)    end    # Lets you do redirects easily as described in Mongrel::RedirectHandler.    # You use it inside the configurator like this:    #    #   redirect("/test", "/to/there") # simple    #   redirect("/to", /t/, 'w') # regexp    #   redirect("/hey", /(w+)/) {|match| ...}  # block    #    def redirect(from, pattern, replacement = nil, &block)      uri from, :handler => Mongrel::RedirectHandler.new(pattern, replacement, &block)    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|         s.run       }      $mongrel_sleeper_thread = Thread.new { loop { sleep 1 } }    end    # Calls .stop on all the configured listeners so they    # stop processing requests (gracefully).  By default it    # assumes that you don't want to restart.    def stop(needs_restart=false)      @listeners.each {|name,s|         s.stop       }      @needs_restart = needs_restart    end    # This method should actually be called *outside* of the    # Configurator block so that you can control it.  In other words    # do it like:  config.join.    def join      @listeners.values.each {|s| s.acceptor.join }    end    # Calling this before you register your URIs to the given location    # will setup a set of handlers that log open files, objects, and the    # parameters for each request.  This helps you track common problems    # found in Rails applications that are either slow or become unresponsive    # after a little while.    #    # You can pass an extra parameter *what* to indicate what you want to     # debug.  For example, if you just want to dump rails stuff then do:    #    #   debug "/", what = [:rails]    #     # And it will only produce the log/mongrel_debug/rails.log file.    # Available options are: :access, :files, :objects, :threads, :rails     #     # NOTE: Use [:files] to get accesses dumped to stderr like with WEBrick.    def debug(location, what = [:access, :files, :objects, :threads, :rails])      require 'mongrel/debug'      handlers = {        :access => "/handlers/requestlog::access",         :files => "/handlers/requestlog::files",         :objects => "/handlers/requestlog::objects",         :threads => "/handlers/requestlog::threads",        :rails => "/handlers/requestlog::params"      }      # turn on the debugging infrastructure, and ObjectTracker is a pig      MongrelDbg.configure      # now we roll through each requested debug type, turn it on and load that plugin      what.each do |type|         MongrelDbg.begin_trace type         uri location, :handler => plugin(handlers[type])      end    end    # Used to allow you to let users specify their own configurations    # inside your Configurator setup.  You pass it a script name and    # it reads it in and does an eval on the contents passing in the right    # binding so they can put their own Configurator statements.    def run_config(script)      open(script) {|f| eval(f.read, proc {self}) }    end    # Sets up the standard signal handlers that are used on most Ruby    # It only configures if the platform is not win32 and doesn't do    # a HUP signal since this is typically framework specific.    #    # Requires a :pid_file option given to Configurator.new to indicate a file to delete.      # It sets the MongrelConfig.needs_restart attribute if     # the start command should reload.  It's up to you to detect this    # and do whatever is needed for a "restart".    #    # This command is safely ignored if the platform is win32 (with a warning)    def setup_signals(options={})      ops = resolve_defaults(options)      # forced shutdown, even if previously restarted (actually just like TERM but for CTRL-C)      trap("INT") { log "INT signal received."; stop(false) }      # clean up the pid file always      at_exit { remove_pid_file }      if RUBY_PLATFORM !~ /mswin/        # graceful shutdown        trap("TERM") { log "TERM signal received."; stop }        trap("USR1") { log "USR1 received, toggling $mongrel_debug_client to #{!$mongrel_debug_client}"; $mongrel_debug_client = !$mongrel_debug_client }        # restart        trap("USR2") { log "USR2 signal received."; stop(true) }        log "Signals ready.  TERM => stop.  USR2 => restart.  INT => stop (no restart)."      else        log "Signals ready.  INT => stop (no restart)."      end    end    # Logs a simple message to STDERR (or the mongrel log if in daemon mode).    def log(msg)      STDERR.print "** ", msg, "\n"    end  endend

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -