sanford 0.10.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -1
- data/README.md +41 -56
- data/Rakefile +0 -1
- data/bench/client.rb +8 -3
- data/bench/{services.rb → config.sanford} +11 -6
- data/bench/{runner.rb → report.rb} +2 -2
- data/bench/report.txt +32 -32
- data/lib/sanford/cli.rb +42 -28
- data/lib/sanford/config_file.rb +79 -0
- data/lib/sanford/{worker.rb → connection_handler.rb} +28 -20
- data/lib/sanford/error_handler.rb +7 -7
- data/lib/sanford/pid_file.rb +42 -0
- data/lib/sanford/process.rb +136 -0
- data/lib/sanford/process_signal.rb +20 -0
- data/lib/sanford/route.rb +48 -0
- data/lib/sanford/router.rb +36 -0
- data/lib/sanford/runner.rb +30 -58
- data/lib/sanford/sanford_runner.rb +19 -9
- data/lib/sanford/server.rb +211 -42
- data/lib/sanford/server_data.rb +47 -0
- data/lib/sanford/service_handler.rb +8 -46
- data/lib/sanford/template_source.rb +19 -2
- data/lib/sanford/test_runner.rb +27 -28
- data/lib/sanford/version.rb +1 -1
- data/lib/sanford.rb +1 -23
- data/sanford.gemspec +4 -5
- data/test/helper.rb +3 -20
- data/test/support/app_server.rb +142 -0
- data/test/support/config.sanford +7 -0
- data/test/support/config_invalid_run.sanford +3 -0
- data/test/support/config_no_run.sanford +0 -0
- data/test/support/fake_server_connection.rb +58 -0
- data/test/support/pid_file_spy.rb +19 -0
- data/test/support/template.erb +1 -0
- data/test/system/server_tests.rb +378 -0
- data/test/system/service_handler_tests.rb +224 -0
- data/test/unit/cli_tests.rb +187 -0
- data/test/unit/config_file_tests.rb +59 -0
- data/test/unit/connection_handler_tests.rb +254 -0
- data/test/unit/error_handler_tests.rb +30 -35
- data/test/unit/pid_file_tests.rb +70 -0
- data/test/unit/process_signal_tests.rb +61 -0
- data/test/unit/process_tests.rb +428 -0
- data/test/unit/route_tests.rb +92 -0
- data/test/unit/router_tests.rb +65 -0
- data/test/unit/runner_tests.rb +61 -15
- data/test/unit/sanford_runner_tests.rb +162 -28
- data/test/unit/sanford_tests.rb +0 -8
- data/test/unit/server_data_tests.rb +87 -0
- data/test/unit/server_tests.rb +502 -21
- data/test/unit/service_handler_tests.rb +114 -219
- data/test/unit/template_engine_tests.rb +1 -1
- data/test/unit/template_source_tests.rb +56 -16
- data/test/unit/test_runner_tests.rb +206 -0
- metadata +67 -67
- data/bench/tasks.rb +0 -41
- data/lib/sanford/config.rb +0 -28
- data/lib/sanford/host.rb +0 -129
- data/lib/sanford/host_data.rb +0 -65
- data/lib/sanford/hosts.rb +0 -38
- data/lib/sanford/manager.rb +0 -275
- data/test/support/fake_connection.rb +0 -36
- data/test/support/helpers.rb +0 -17
- data/test/support/service_handlers.rb +0 -154
- data/test/support/services.rb +0 -123
- data/test/support/simple_client.rb +0 -62
- data/test/system/request_handling_tests.rb +0 -306
- data/test/unit/config_tests.rb +0 -56
- data/test/unit/host_data_tests.rb +0 -71
- data/test/unit/host_tests.rb +0 -141
- data/test/unit/hosts_tests.rb +0 -50
- data/test/unit/manager_tests.rb +0 -195
- data/test/unit/worker_tests.rb +0 -24
    
        data/lib/sanford/host_data.rb
    DELETED
    
    | @@ -1,65 +0,0 @@ | |
| 1 | 
            -
            require 'sanford/service_handler'
         | 
| 2 | 
            -
            require 'sanford/sanford_runner'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            module Sanford
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              class HostData
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                # When trying to run a server for a host, we need to build up the host's
         | 
| 9 | 
            -
                # data to increase the performance of the server. This is done by
         | 
| 10 | 
            -
                # constantizing a host's handlers and merging a host's configuration with
         | 
| 11 | 
            -
                # optional overrides.
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                # NOTE: The `name` attribute shouldn't be removed, it is used to identify
         | 
| 14 | 
            -
                # a `HostData`, particularly in error handlers
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                attr_reader :name, :logger, :verbose, :keep_alive, :error_procs
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                def initialize(service_host, options = nil)
         | 
| 19 | 
            -
                  service_host.configuration.init_procs.each(&:call)
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                  overrides = self.remove_nil_values(options || {})
         | 
| 22 | 
            -
                  configuration = service_host.configuration.to_hash.merge(overrides)
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                  @name        = configuration[:name]
         | 
| 25 | 
            -
                  @logger      = configuration[:logger]
         | 
| 26 | 
            -
                  @verbose     = configuration[:verbose_logging]
         | 
| 27 | 
            -
                  @keep_alive  = configuration[:receives_keep_alive]
         | 
| 28 | 
            -
                  @error_procs = configuration[:error_procs]
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                  @handlers = service_host.services.inject({}) do |h, (name, handler_class_name)|
         | 
| 31 | 
            -
                    h.merge({ name => self.constantize(handler_class_name) })
         | 
| 32 | 
            -
                  end
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                def handler_class_for(service)
         | 
| 36 | 
            -
                  @handlers[service] || raise(Sanford::NotFoundError)
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                def run(handler_class, request)
         | 
| 40 | 
            -
                  SanfordRunner.new(handler_class, request, self.logger).run
         | 
| 41 | 
            -
                end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                protected
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                def constantize(handler_class_name)
         | 
| 46 | 
            -
                  Sanford::ServiceHandler.constantize(handler_class_name) ||
         | 
| 47 | 
            -
                    raise(Sanford::NoHandlerClassError.new(handler_class_name))
         | 
| 48 | 
            -
                end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                def remove_nil_values(hash)
         | 
| 51 | 
            -
                  hash.inject({}){|h, (k, v)| !v.nil? ? h.merge({ k => v }) : h }
         | 
| 52 | 
            -
                end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
              end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
              NotFoundError = Class.new(RuntimeError)
         | 
| 57 | 
            -
             | 
| 58 | 
            -
              class NoHandlerClassError < RuntimeError
         | 
| 59 | 
            -
                def initialize(handler_class_name)
         | 
| 60 | 
            -
                  super "Sanford couldn't find the service handler '#{handler_class_name}'."\
         | 
| 61 | 
            -
                        " It doesn't exist or hasn't been required in yet."
         | 
| 62 | 
            -
                end
         | 
| 63 | 
            -
              end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
            end
         | 
    
        data/lib/sanford/hosts.rb
    DELETED
    
    | @@ -1,38 +0,0 @@ | |
| 1 | 
            -
            require 'set'
         | 
| 2 | 
            -
            require 'sanford/host'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            module Sanford
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              class Hosts
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                def initialize(values = [])
         | 
| 9 | 
            -
                  @set = Set.new(values)
         | 
| 10 | 
            -
                end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                def method_missing(method, *args, &block)
         | 
| 13 | 
            -
                  @set.send(method, *args, &block)
         | 
| 14 | 
            -
                end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                def respond_to?(method)
         | 
| 17 | 
            -
                  super || @set.respond_to?(method)
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                # We want class names to take precedence over a configured name, so that if
         | 
| 21 | 
            -
                # a user specifies a specific class, they always get it
         | 
| 22 | 
            -
                def find(name)
         | 
| 23 | 
            -
                  find_by_class_name(name) || find_by_name(name)
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                private
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                def find_by_class_name(class_name)
         | 
| 29 | 
            -
                  @set.detect{|host_class| host_class.to_s == class_name.to_s }
         | 
| 30 | 
            -
                end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                def find_by_name(name)
         | 
| 33 | 
            -
                  @set.detect{|host_class| host_class.name == name.to_s }
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
              end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
            end
         | 
    
        data/lib/sanford/manager.rb
    DELETED
    
    | @@ -1,275 +0,0 @@ | |
| 1 | 
            -
            require 'sanford/cli'
         | 
| 2 | 
            -
            require 'sanford/server'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            module Sanford
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              module Manager
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                def self.call(action, options = nil)
         | 
| 9 | 
            -
                  get_handler_class(action).new(options).tap{ |manager| manager.send(action) }
         | 
| 10 | 
            -
                end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                def self.get_handler_class(action)
         | 
| 13 | 
            -
                  case action.to_sym
         | 
| 14 | 
            -
                  when :start, :run
         | 
| 15 | 
            -
                    ServerHandler
         | 
| 16 | 
            -
                  when :stop, :restart
         | 
| 17 | 
            -
                    SignalHandler
         | 
| 18 | 
            -
                  end
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                class Config
         | 
| 22 | 
            -
                  attr_reader :host_name, :host, :ip, :port, :pid, :pid_file, :restart_dir
         | 
| 23 | 
            -
                  attr_reader :file_descriptor, :client_file_descriptors
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                  def initialize(opts = nil)
         | 
| 26 | 
            -
                    options = OpenStruct.new(opts || {})
         | 
| 27 | 
            -
                    @host_name = ENV['SANFORD_HOST'] || options.host
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                    @host = @host_name ? Sanford.hosts.find(@host_name) : Sanford.hosts.first
         | 
| 30 | 
            -
                    @host ||= NullHost.new
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                    @file_descriptor = ENV['SANFORD_SERVER_FD'] || options.file_descriptor
         | 
| 33 | 
            -
                    @file_descriptor = @file_descriptor.to_i if @file_descriptor
         | 
| 34 | 
            -
                    @ip   = ENV['SANFORD_IP']   || options.ip   || @host.ip
         | 
| 35 | 
            -
                    @port = ENV['SANFORD_PORT'] || options.port || @host.port
         | 
| 36 | 
            -
                    @port = @port.to_i if @port
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                    client_fds_str = ENV['SANFORD_CLIENT_FDS'] || options.client_fds || ""
         | 
| 39 | 
            -
                    @client_file_descriptors = client_fds_str.split(',').map(&:to_i)
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                    @pid_file = PIDFile.new(ENV['SANFORD_PID_FILE'] || options.pid_file || @host.pid_file)
         | 
| 42 | 
            -
                    @pid      = options.pid || @pid_file.pid
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                    @restart_dir = ENV['SANFORD_RESTART_DIR'] || options.restart_dir
         | 
| 45 | 
            -
                  end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                  def listen_args
         | 
| 48 | 
            -
                    @file_descriptor ? [ @file_descriptor ] : [ @ip, @port ]
         | 
| 49 | 
            -
                  end
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                  def has_listen_args?
         | 
| 52 | 
            -
                    !!@file_descriptor || !!(@ip && @port)
         | 
| 53 | 
            -
                  end
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                  def found_host?
         | 
| 56 | 
            -
                    !@host.kind_of?(NullHost)
         | 
| 57 | 
            -
                  end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
                  class NullHost
         | 
| 60 | 
            -
                    [ :ip, :port, :pid_file ].each do |method_name|
         | 
| 61 | 
            -
                      define_method(method_name){ }
         | 
| 62 | 
            -
                    end
         | 
| 63 | 
            -
                  end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                  class PIDFile
         | 
| 66 | 
            -
                    DEF_FILE = '/dev/null'
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                    def initialize(path)
         | 
| 69 | 
            -
                      @path = (path || DEF_FILE).to_s
         | 
| 70 | 
            -
                    end
         | 
| 71 | 
            -
             | 
| 72 | 
            -
                    def pid
         | 
| 73 | 
            -
                      pid = File.read(@path).strip if File.exists?(@path)
         | 
| 74 | 
            -
                      pid.to_i if pid && !pid.empty?
         | 
| 75 | 
            -
                    end
         | 
| 76 | 
            -
             | 
| 77 | 
            -
                    def write
         | 
| 78 | 
            -
                      begin
         | 
| 79 | 
            -
                        File.open(@path, 'w'){|f| f.puts Process.pid }
         | 
| 80 | 
            -
                      rescue Errno::ENOENT => err
         | 
| 81 | 
            -
                        e = RuntimeError.new("Can't write pid to file `#{@path}`")
         | 
| 82 | 
            -
                        e.set_backtrace(err.backtrace)
         | 
| 83 | 
            -
                        raise e
         | 
| 84 | 
            -
                      end
         | 
| 85 | 
            -
                    end
         | 
| 86 | 
            -
             | 
| 87 | 
            -
                    def remove
         | 
| 88 | 
            -
                      FileUtils.rm_f(@path)
         | 
| 89 | 
            -
                    end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                    def to_s
         | 
| 92 | 
            -
                      @path
         | 
| 93 | 
            -
                    end
         | 
| 94 | 
            -
                  end
         | 
| 95 | 
            -
             | 
| 96 | 
            -
                end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                class ServerHandler
         | 
| 99 | 
            -
             | 
| 100 | 
            -
                  def initialize(options = nil)
         | 
| 101 | 
            -
                    @config = Config.new(options)
         | 
| 102 | 
            -
                    raise Sanford::NoHostError.new(@config.host_name) if !@config.found_host?
         | 
| 103 | 
            -
                    raise Sanford::InvalidHostError.new(@config.host) if !@config.has_listen_args?
         | 
| 104 | 
            -
                    @host   = @config.host
         | 
| 105 | 
            -
                    @logger = @host.logger
         | 
| 106 | 
            -
             | 
| 107 | 
            -
                    @server_options = {}
         | 
| 108 | 
            -
                    # FUTURE allow passing through dat-tcp options (min/max workers)
         | 
| 109 | 
            -
                    # FUTURE merge in host options for verbose / keep_alive
         | 
| 110 | 
            -
             | 
| 111 | 
            -
                    @restart_cmd = RestartCmd.new(@config)
         | 
| 112 | 
            -
                  end
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                  def run
         | 
| 115 | 
            -
                    self.run! false
         | 
| 116 | 
            -
                  end
         | 
| 117 | 
            -
             | 
| 118 | 
            -
                  def start
         | 
| 119 | 
            -
                    self.run! true
         | 
| 120 | 
            -
                  end
         | 
| 121 | 
            -
             | 
| 122 | 
            -
                  protected
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                  def run!(daemonize = false)
         | 
| 125 | 
            -
                    daemonize!(true) if daemonize && !ENV['SANFORD_SKIP_DAEMONIZE']
         | 
| 126 | 
            -
                    Sanford::Server.new(@host, @server_options).tap do |server|
         | 
| 127 | 
            -
                      log "Starting #{@host.name} server..."
         | 
| 128 | 
            -
             | 
| 129 | 
            -
                      server.listen(*@config.listen_args)
         | 
| 130 | 
            -
                      $0 = ProcessName.new(@host.name, server.ip, server.port)
         | 
| 131 | 
            -
                      log "Listening on #{server.ip}:#{server.port}"
         | 
| 132 | 
            -
             | 
| 133 | 
            -
                      @config.pid_file.write
         | 
| 134 | 
            -
                      log "PID: #{Process.pid}"
         | 
| 135 | 
            -
             | 
| 136 | 
            -
                      Signal.trap("TERM"){ self.stop!(server) }
         | 
| 137 | 
            -
                      Signal.trap("INT"){  self.halt!(server) }
         | 
| 138 | 
            -
                      Signal.trap("USR2"){ self.restart!(server) }
         | 
| 139 | 
            -
             | 
| 140 | 
            -
                      server_thread = server.run(@config.client_file_descriptors)
         | 
| 141 | 
            -
                      log "#{@host.name} server started and ready."
         | 
| 142 | 
            -
                      server_thread.join
         | 
| 143 | 
            -
                    end
         | 
| 144 | 
            -
                  rescue RuntimeError => err
         | 
| 145 | 
            -
                    log "Error: #{err.message}"
         | 
| 146 | 
            -
                    log "#{@host.name} server never started."
         | 
| 147 | 
            -
                  ensure
         | 
| 148 | 
            -
                    @config.pid_file.remove
         | 
| 149 | 
            -
                  end
         | 
| 150 | 
            -
             | 
| 151 | 
            -
                  def restart!(server)
         | 
| 152 | 
            -
                    log "Restarting #{@host.name} server..."
         | 
| 153 | 
            -
                    server.pause
         | 
| 154 | 
            -
                    log "server paused"
         | 
| 155 | 
            -
             | 
| 156 | 
            -
                    ENV['SANFORD_HOST']           = @host.name
         | 
| 157 | 
            -
                    ENV['SANFORD_SERVER_FD']      = server.file_descriptor.to_s
         | 
| 158 | 
            -
                    ENV['SANFORD_CLIENT_FDS']     = server.client_file_descriptors.join(',')
         | 
| 159 | 
            -
                    ENV['SANFORD_SKIP_DAEMONIZE'] = 'yes'
         | 
| 160 | 
            -
             | 
| 161 | 
            -
                    log "calling exec ..."
         | 
| 162 | 
            -
                    Dir.chdir @restart_cmd.dir
         | 
| 163 | 
            -
                    Kernel.exec(*@restart_cmd.argv)
         | 
| 164 | 
            -
                  end
         | 
| 165 | 
            -
             | 
| 166 | 
            -
                  def stop!(server)
         | 
| 167 | 
            -
                    log "Stopping #{@host.name} server..."
         | 
| 168 | 
            -
                    server.stop
         | 
| 169 | 
            -
                    log "#{@host.name} server stopped."
         | 
| 170 | 
            -
                  end
         | 
| 171 | 
            -
             | 
| 172 | 
            -
                  def halt!(server)
         | 
| 173 | 
            -
                    log "Halting #{@host.name} server..."
         | 
| 174 | 
            -
                    server.halt false
         | 
| 175 | 
            -
                    log "#{@host.name} server halted."
         | 
| 176 | 
            -
                  end
         | 
| 177 | 
            -
             | 
| 178 | 
            -
                  # Full explanation: http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16
         | 
| 179 | 
            -
                  def daemonize!(no_chdir = false, no_close = false)
         | 
| 180 | 
            -
                    exit if fork
         | 
| 181 | 
            -
                    Process.setsid
         | 
| 182 | 
            -
                    exit if fork
         | 
| 183 | 
            -
                    Dir.chdir "/" unless no_chdir
         | 
| 184 | 
            -
                    if !no_close
         | 
| 185 | 
            -
                      null = File.open "/dev/null", 'w'
         | 
| 186 | 
            -
                      STDIN.reopen null
         | 
| 187 | 
            -
                      STDOUT.reopen null
         | 
| 188 | 
            -
                      STDERR.reopen null
         | 
| 189 | 
            -
                    end
         | 
| 190 | 
            -
                    return 0
         | 
| 191 | 
            -
                  end
         | 
| 192 | 
            -
             | 
| 193 | 
            -
                  def log(message)
         | 
| 194 | 
            -
                    @logger.info "[Sanford] #{message}"
         | 
| 195 | 
            -
                  end
         | 
| 196 | 
            -
             | 
| 197 | 
            -
                  class ProcessName < String
         | 
| 198 | 
            -
                    def initialize(name, ip, port)
         | 
| 199 | 
            -
                      super "#{[ name, ip, port ].join('_')}"
         | 
| 200 | 
            -
                    end
         | 
| 201 | 
            -
                  end
         | 
| 202 | 
            -
             | 
| 203 | 
            -
                  class RestartCmd
         | 
| 204 | 
            -
                    attr_reader :argv, :dir
         | 
| 205 | 
            -
             | 
| 206 | 
            -
                    def initialize(config = nil)
         | 
| 207 | 
            -
                      require 'rubygems'
         | 
| 208 | 
            -
                      config ||= OpenStruct.new
         | 
| 209 | 
            -
                      @dir = config.restart_dir || get_pwd
         | 
| 210 | 
            -
                      @argv = [ Gem.ruby, $0, ARGV.dup ].flatten
         | 
| 211 | 
            -
                    end
         | 
| 212 | 
            -
             | 
| 213 | 
            -
                    protected
         | 
| 214 | 
            -
             | 
| 215 | 
            -
                    # Trick from puma/unicorn. Favor PWD because it contains an unresolved
         | 
| 216 | 
            -
                    # symlink. This is useful when restarting after deploying; the original
         | 
| 217 | 
            -
                    # directory may be removed, but the symlink is pointing to a new
         | 
| 218 | 
            -
                    # directory.
         | 
| 219 | 
            -
                    def get_pwd
         | 
| 220 | 
            -
                      env_stat = File.stat(ENV['PWD'])
         | 
| 221 | 
            -
                      pwd_stat = File.stat(Dir.pwd)
         | 
| 222 | 
            -
                      if env_stat.ino == pwd_stat.ino && env_stat.dev == pwd_stat.dev
         | 
| 223 | 
            -
                        ENV['PWD']
         | 
| 224 | 
            -
                      else
         | 
| 225 | 
            -
                        Dir.pwd
         | 
| 226 | 
            -
                      end
         | 
| 227 | 
            -
                    end
         | 
| 228 | 
            -
             | 
| 229 | 
            -
                  end
         | 
| 230 | 
            -
             | 
| 231 | 
            -
                end
         | 
| 232 | 
            -
             | 
| 233 | 
            -
                class SignalHandler
         | 
| 234 | 
            -
             | 
| 235 | 
            -
                  def initialize(options = nil)
         | 
| 236 | 
            -
                    @config = Config.new(options)
         | 
| 237 | 
            -
                    raise Sanford::NoPIDError.new if !@config.pid
         | 
| 238 | 
            -
                  end
         | 
| 239 | 
            -
             | 
| 240 | 
            -
                  def stop
         | 
| 241 | 
            -
                    Process.kill("TERM", @config.pid)
         | 
| 242 | 
            -
                  end
         | 
| 243 | 
            -
             | 
| 244 | 
            -
                  def restart
         | 
| 245 | 
            -
                    Process.kill("USR2", @config.pid)
         | 
| 246 | 
            -
                  end
         | 
| 247 | 
            -
             | 
| 248 | 
            -
                end
         | 
| 249 | 
            -
             | 
| 250 | 
            -
              end
         | 
| 251 | 
            -
             | 
| 252 | 
            -
              class NoHostError < CLIRB::Error
         | 
| 253 | 
            -
                def initialize(host_name)
         | 
| 254 | 
            -
                  message = if Sanford.hosts.empty?
         | 
| 255 | 
            -
                    "No hosts have been defined. Please define a host before trying to run Sanford."
         | 
| 256 | 
            -
                  else
         | 
| 257 | 
            -
                    "A host couldn't be found with the name #{host_name.inspect}. "
         | 
| 258 | 
            -
                  end
         | 
| 259 | 
            -
                  super message
         | 
| 260 | 
            -
                end
         | 
| 261 | 
            -
              end
         | 
| 262 | 
            -
             | 
| 263 | 
            -
              class InvalidHostError < CLIRB::Error
         | 
| 264 | 
            -
                def initialize(host)
         | 
| 265 | 
            -
                  super "A port must be configured or provided to run a server for '#{host}'"
         | 
| 266 | 
            -
                end
         | 
| 267 | 
            -
              end
         | 
| 268 | 
            -
             | 
| 269 | 
            -
              class NoPIDError < CLIRB::Error
         | 
| 270 | 
            -
                def initialize
         | 
| 271 | 
            -
                  super "A PID or PID file is required"
         | 
| 272 | 
            -
                end
         | 
| 273 | 
            -
              end
         | 
| 274 | 
            -
             | 
| 275 | 
            -
            end
         | 
| @@ -1,36 +0,0 @@ | |
| 1 | 
            -
            class FakeConnection
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              attr_reader :read_data, :response, :write_stream_closed
         | 
| 4 | 
            -
             | 
| 5 | 
            -
              def self.with_request(name, params = {}, raise_on_write = false)
         | 
| 6 | 
            -
                request = Sanford::Protocol::Request.new(name, params)
         | 
| 7 | 
            -
                self.new(request.to_hash, raise_on_write)
         | 
| 8 | 
            -
              end
         | 
| 9 | 
            -
             | 
| 10 | 
            -
              def initialize(*args)
         | 
| 11 | 
            -
                if args.first.kind_of?(Sanford::Protocol::Connection)
         | 
| 12 | 
            -
                  protocol_connection = args.first
         | 
| 13 | 
            -
                  @read_data = proc{ protocol_connection.read }
         | 
| 14 | 
            -
                  @write_data = proc{|data| protocol_connection.write(data) }
         | 
| 15 | 
            -
                else
         | 
| 16 | 
            -
                  @read_data, @raise_on_write = args
         | 
| 17 | 
            -
                end
         | 
| 18 | 
            -
              end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
              def read_data
         | 
| 21 | 
            -
                @read_data.kind_of?(Proc) ? @read_data.call : @read_data
         | 
| 22 | 
            -
              end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
              def write_data(data)
         | 
| 25 | 
            -
                if @raise_on_write
         | 
| 26 | 
            -
                  @raise_on_write = false
         | 
| 27 | 
            -
                  raise 'test fail'
         | 
| 28 | 
            -
                end
         | 
| 29 | 
            -
                @response = Sanford::Protocol::Response.parse(data)
         | 
| 30 | 
            -
              end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
              def close_write
         | 
| 33 | 
            -
                @write_stream_closed = true
         | 
| 34 | 
            -
              end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
            end
         | 
    
        data/test/support/helpers.rb
    DELETED
    
    | @@ -1,17 +0,0 @@ | |
| 1 | 
            -
            module Test
         | 
| 2 | 
            -
              module SpawnServerHelper
         | 
| 3 | 
            -
             | 
| 4 | 
            -
                def start_server(host, &block)
         | 
| 5 | 
            -
                  begin
         | 
| 6 | 
            -
                    server = Sanford::Server.new(host, { :ready_timeout => 0.1 })
         | 
| 7 | 
            -
                    server.listen(host.ip, host.port)
         | 
| 8 | 
            -
                    thread = server.run
         | 
| 9 | 
            -
                    yield
         | 
| 10 | 
            -
                  ensure
         | 
| 11 | 
            -
                    server.halt if server
         | 
| 12 | 
            -
                    thread.join if thread
         | 
| 13 | 
            -
                  end
         | 
| 14 | 
            -
                end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
            end
         | 
| @@ -1,154 +0,0 @@ | |
| 1 | 
            -
            class BasicServiceHandler
         | 
| 2 | 
            -
              include Sanford::ServiceHandler
         | 
| 3 | 
            -
             | 
| 4 | 
            -
              def run!
         | 
| 5 | 
            -
                { 'name' => 'Joe Test', 'email' => "joe.test@example.com" }
         | 
| 6 | 
            -
              end
         | 
| 7 | 
            -
             | 
| 8 | 
            -
            end
         | 
| 9 | 
            -
             | 
| 10 | 
            -
            class SerializeErrorServiceHandler
         | 
| 11 | 
            -
              include Sanford::ServiceHandler
         | 
| 12 | 
            -
             | 
| 13 | 
            -
              # return data that fails BSON serialization
         | 
| 14 | 
            -
              # BSON errors if it is sent date/datetime values
         | 
| 15 | 
            -
              def run!
         | 
| 16 | 
            -
                { 'date' => Date.today,
         | 
| 17 | 
            -
                  'datetime' => DateTime.now
         | 
| 18 | 
            -
                }
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
            end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            module CallbackServiceHandler
         | 
| 24 | 
            -
             | 
| 25 | 
            -
              def self.included(receiver)
         | 
| 26 | 
            -
                receiver.class_eval do
         | 
| 27 | 
            -
                  attr_reader :before_called, :after_called
         | 
| 28 | 
            -
                  attr_reader :before_init_called, :init_bang_called, :after_init_called
         | 
| 29 | 
            -
                  attr_reader :before_run_called, :run_bang_called, :after_run_called
         | 
| 30 | 
            -
                  attr_reader :second_before_init_called, :second_after_run_called
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                  before do
         | 
| 33 | 
            -
                    @before_called = true
         | 
| 34 | 
            -
                  end
         | 
| 35 | 
            -
                  after do
         | 
| 36 | 
            -
                    @after_called = true
         | 
| 37 | 
            -
                  end
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                  before_init do
         | 
| 40 | 
            -
                    @before_init_called = true
         | 
| 41 | 
            -
                  end
         | 
| 42 | 
            -
                  before_init do
         | 
| 43 | 
            -
                    @second_before_init_called = true
         | 
| 44 | 
            -
                  end
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                  after_init do
         | 
| 47 | 
            -
                    @after_init_called = true
         | 
| 48 | 
            -
                  end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                  before_run do
         | 
| 51 | 
            -
                    @before_run_called = true
         | 
| 52 | 
            -
                  end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                  after_run do
         | 
| 55 | 
            -
                    @after_run_called = true
         | 
| 56 | 
            -
                  end
         | 
| 57 | 
            -
                  after_run do
         | 
| 58 | 
            -
                    @second_after_run_called = true
         | 
| 59 | 
            -
                  end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                end
         | 
| 62 | 
            -
             | 
| 63 | 
            -
              end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
              def init!
         | 
| 66 | 
            -
                @init_bang_called = true
         | 
| 67 | 
            -
              end
         | 
| 68 | 
            -
             | 
| 69 | 
            -
              def run!
         | 
| 70 | 
            -
                @run_bang_called = true
         | 
| 71 | 
            -
              end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
            end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
            class FlagServiceHandler
         | 
| 76 | 
            -
              include Sanford::ServiceHandler
         | 
| 77 | 
            -
              include CallbackServiceHandler
         | 
| 78 | 
            -
             | 
| 79 | 
            -
            end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
            class HaltingBehaviorServiceHandler
         | 
| 82 | 
            -
              include Sanford::ServiceHandler
         | 
| 83 | 
            -
              include CallbackServiceHandler
         | 
| 84 | 
            -
             | 
| 85 | 
            -
              before_init do
         | 
| 86 | 
            -
                halt_when('before_init')
         | 
| 87 | 
            -
              end
         | 
| 88 | 
            -
             | 
| 89 | 
            -
              def init!
         | 
| 90 | 
            -
                super
         | 
| 91 | 
            -
                halt_when('init!')
         | 
| 92 | 
            -
              end
         | 
| 93 | 
            -
             | 
| 94 | 
            -
              after_init do
         | 
| 95 | 
            -
                halt_when('after_init')
         | 
| 96 | 
            -
              end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
              before_run do
         | 
| 99 | 
            -
                halt_when('before_run')
         | 
| 100 | 
            -
              end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
              def run!
         | 
| 103 | 
            -
                super
         | 
| 104 | 
            -
                halt_when('run!')
         | 
| 105 | 
            -
              end
         | 
| 106 | 
            -
             | 
| 107 | 
            -
              after_run do
         | 
| 108 | 
            -
                halt_when('after_run')
         | 
| 109 | 
            -
              end
         | 
| 110 | 
            -
             | 
| 111 | 
            -
              def halt_when(method_name)
         | 
| 112 | 
            -
                return if ![*params['when']].include?(method_name)
         | 
| 113 | 
            -
                halt(200, {
         | 
| 114 | 
            -
                  :message  => "#{method_name} halting",
         | 
| 115 | 
            -
                  :data     => {
         | 
| 116 | 
            -
                    :before_init_called => @before_init_called,
         | 
| 117 | 
            -
                    :init_bang_called   => @init_bang_called,
         | 
| 118 | 
            -
                    :after_init_called  => @after_init_called,
         | 
| 119 | 
            -
                    :before_run_called  => @before_run_called,
         | 
| 120 | 
            -
                    :run_bang_called    => @run_bang_called,
         | 
| 121 | 
            -
                    :after_run_called   => @after_run_called
         | 
| 122 | 
            -
                  }
         | 
| 123 | 
            -
                })
         | 
| 124 | 
            -
              end
         | 
| 125 | 
            -
             | 
| 126 | 
            -
            end
         | 
| 127 | 
            -
             | 
| 128 | 
            -
            class RenderHandler
         | 
| 129 | 
            -
              include Sanford::ServiceHandler
         | 
| 130 | 
            -
             | 
| 131 | 
            -
              def run!
         | 
| 132 | 
            -
                render params['template_name']
         | 
| 133 | 
            -
              end
         | 
| 134 | 
            -
            end
         | 
| 135 | 
            -
             | 
| 136 | 
            -
            class RunOtherHandler
         | 
| 137 | 
            -
              include Sanford::ServiceHandler
         | 
| 138 | 
            -
             | 
| 139 | 
            -
              def run!
         | 
| 140 | 
            -
                response = run_handler(HaltServiceHandler, 'code' => 200, 'data' => 'RunOtherHandler')
         | 
| 141 | 
            -
                response.data
         | 
| 142 | 
            -
              end
         | 
| 143 | 
            -
            end
         | 
| 144 | 
            -
             | 
| 145 | 
            -
            class HaltServiceHandler
         | 
| 146 | 
            -
              include Sanford::ServiceHandler
         | 
| 147 | 
            -
             | 
| 148 | 
            -
              def run!
         | 
| 149 | 
            -
                halt params['code'], :message => params['message'], :data => params['data']
         | 
| 150 | 
            -
              end
         | 
| 151 | 
            -
             | 
| 152 | 
            -
            end
         | 
| 153 | 
            -
             | 
| 154 | 
            -
            class InvalidServiceHandler; end
         | 
    
        data/test/support/services.rb
    DELETED
    
    | @@ -1,123 +0,0 @@ | |
| 1 | 
            -
            require 'logger'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            class TestHost
         | 
| 4 | 
            -
              include Sanford::Host
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              attr_accessor :init_has_been_called
         | 
| 7 | 
            -
             | 
| 8 | 
            -
              init do
         | 
| 9 | 
            -
                self.init_has_been_called = true
         | 
| 10 | 
            -
              end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
              ip       'localhost'
         | 
| 13 | 
            -
              port     12000
         | 
| 14 | 
            -
              pid_file File.expand_path('../../../tmp/test_host.pid', __FILE__)
         | 
| 15 | 
            -
             | 
| 16 | 
            -
              logger(Logger.new(File.expand_path("../../../log/test.log", __FILE__)).tap do |logger|
         | 
| 17 | 
            -
                logger.level = Logger::DEBUG
         | 
| 18 | 
            -
              end)
         | 
| 19 | 
            -
              verbose_logging false
         | 
| 20 | 
            -
             | 
| 21 | 
            -
              error do |exception, host_data, request|
         | 
| 22 | 
            -
                if exception.kind_of?(::MyCustomError)
         | 
| 23 | 
            -
                  Sanford::Protocol::Response.new([ 987, 'custom error!' ])
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
              end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
              service_handler_ns 'TestHost'
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              service :echo,          'Echo'
         | 
| 30 | 
            -
              service 'bad',          'Bad'
         | 
| 31 | 
            -
              service 'multiply',     'Multiply'
         | 
| 32 | 
            -
              service 'halt_it',      '::TestHost::HaltIt'
         | 
| 33 | 
            -
              service 'authorized',   'Authorized'
         | 
| 34 | 
            -
              service 'custom_error', 'CustomError'
         | 
| 35 | 
            -
             | 
| 36 | 
            -
              class Echo
         | 
| 37 | 
            -
                include Sanford::ServiceHandler
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                def run!
         | 
| 40 | 
            -
                  params['message']
         | 
| 41 | 
            -
                end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
              end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
              class Bad
         | 
| 46 | 
            -
                include Sanford::ServiceHandler
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                def run!
         | 
| 49 | 
            -
                  raise "hahaha"
         | 
| 50 | 
            -
                end
         | 
| 51 | 
            -
              end
         | 
| 52 | 
            -
             | 
| 53 | 
            -
              class Multiply
         | 
| 54 | 
            -
                include Sanford::ServiceHandler
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                def init!
         | 
| 57 | 
            -
                  @number = params['number'] || 1
         | 
| 58 | 
            -
                end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                def run!
         | 
| 61 | 
            -
                  @number * 2
         | 
| 62 | 
            -
                end
         | 
| 63 | 
            -
              end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
              class HaltIt
         | 
| 66 | 
            -
                include Sanford::ServiceHandler
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                def run!
         | 
| 69 | 
            -
                  halt 728, {
         | 
| 70 | 
            -
                    :message  => "I do what I want",
         | 
| 71 | 
            -
                    :data     => [ 1, true, 'yes' ]
         | 
| 72 | 
            -
                  }
         | 
| 73 | 
            -
                end
         | 
| 74 | 
            -
              end
         | 
| 75 | 
            -
             | 
| 76 | 
            -
              class Authorized
         | 
| 77 | 
            -
                include Sanford::ServiceHandler
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                before_run do
         | 
| 80 | 
            -
                  halt 401, :message => "Not authorized"
         | 
| 81 | 
            -
                end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
              end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
              ::MyCustomError = Class.new(RuntimeError)
         | 
| 86 | 
            -
             | 
| 87 | 
            -
              class CustomError
         | 
| 88 | 
            -
                include Sanford::ServiceHandler
         | 
| 89 | 
            -
             | 
| 90 | 
            -
                def run!
         | 
| 91 | 
            -
                  raise ::MyCustomError
         | 
| 92 | 
            -
                end
         | 
| 93 | 
            -
             | 
| 94 | 
            -
              end
         | 
| 95 | 
            -
             | 
| 96 | 
            -
            end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
            class MyHost
         | 
| 99 | 
            -
              include Sanford::Host
         | 
| 100 | 
            -
             | 
| 101 | 
            -
              name     'my_host'
         | 
| 102 | 
            -
              ip       'my.local'
         | 
| 103 | 
            -
              pid_file File.expand_path('../../../tmp/my_host.pid', __FILE__)
         | 
| 104 | 
            -
            end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
            class InvalidHost
         | 
| 107 | 
            -
              include Sanford::Host
         | 
| 108 | 
            -
             | 
| 109 | 
            -
              name 'invalid_host'
         | 
| 110 | 
            -
            end
         | 
| 111 | 
            -
             | 
| 112 | 
            -
            class UndefinedHandlersHost
         | 
| 113 | 
            -
              include Sanford::Host
         | 
| 114 | 
            -
             | 
| 115 | 
            -
              port 12345
         | 
| 116 | 
            -
             | 
| 117 | 
            -
              service 'undefined', 'ThisIsNotDefined'
         | 
| 118 | 
            -
             | 
| 119 | 
            -
            end
         | 
| 120 | 
            -
             | 
| 121 | 
            -
            class EmptyHost
         | 
| 122 | 
            -
              include Sanford::Host
         | 
| 123 | 
            -
            end
         |