From 6ca4c4ca0afee78c642658bb5a434730f1916139 Mon Sep 17 00:00:00 2001 From: schneems Date: Wed, 3 Feb 2016 14:06:00 -0600 Subject: [PATCH] Move more logic out of CLI Focus on removing @options. Delegate all actions to launcher. --- lib/puma/cli.rb | 134 ++++++----------------------------------- lib/puma/detect.rb | 9 ++- lib/puma/launcher.rb | 138 +++++++++++++++++++++++++++++++++++++++++-- test/test_cli.rb | 2 +- 4 files changed, 160 insertions(+), 123 deletions(-) diff --git a/lib/puma/cli.rb b/lib/puma/cli.rb index 8e5b7bda..9e1a56f8 100644 --- a/lib/puma/cli.rb +++ b/lib/puma/cli.rb @@ -50,7 +50,6 @@ module Puma @config = nil setup_options - generate_restart_data @binder = Binder.new(@events) @binder.import_from_env @@ -67,12 +66,22 @@ module Puma @launcher.events = self.events @launcher.config = self.config @launcher.binder = self.binder + @launcher.argv = @argv + @launcher.setup(@options) end ## BACKWARDS COMPAT FOR TESTS + def error(str) + @launcher.error(str) + end + + def debug(str) + @launcher.debug(str) + end + def delete_pidfile @launcher.delete_pidfile end @@ -121,29 +130,17 @@ module Puma # The Events object used to output information. attr_reader :events - # Delegate +error+ to +@events+ - # - def error(str) - @events.error str - end - - def debug(str) - @events.log "- #{str}" if @options[:debug] - end def clustered? - # remove eventually - @options[:workers] > 0 + @launcher.clustered? end def jruby? - # remove eventually - IS_JRUBY + Puma.jruby? end def windows? - # remove eventually - RUBY_PLATFORM =~ /mswin32|ming32/ + Puma.windows? end <<<<<<< HEAD @@ -195,63 +192,30 @@ module Puma ======= >>>>>>> Initial Seperation of CLI and Server Launcher work def jruby_daemon_start - require 'puma/jruby_restart' - JRubyRestart.daemon_start(@restart_dir, restart_args) + @launcher.jruby_daemon_start end def restart! - @options[:on_restart].each do |block| - block.call self - end - - if jruby? - close_binder_listeners - - require 'puma/jruby_restart' - JRubyRestart.chdir_exec(@restart_dir, restart_args) - elsif windows? - close_binder_listeners - - argv = restart_args - Dir.chdir(@restart_dir) - argv += [redirects] if RUBY_VERSION >= '1.9' - Kernel.exec(*argv) - else - redirects = {:close_others => true} - @binder.listeners.each_with_index do |(l, io), i| - ENV["PUMA_INHERIT_#{i}"] = "#{io.to_i}:#{l}" - redirects[io.to_i] = io.to_i - end - - argv = restart_args - Dir.chdir(@restart_dir) - argv += [redirects] if RUBY_VERSION >= '1.9' - Kernel.exec(*argv) - end + @launcher.restart! end # Parse the options, load the rackup, start the server and wait # for it to finish. # def run - @runner = @launcher.runner @launcher.run end def reload_worker_directory - @runner.reload_worker_directory if @runner.respond_to?(:reload_worker_directory) + @launcher.reload_worker_directory end def phased_restart - unless @runner.respond_to?(:phased_restart) and @runner.phased_restart - log "* phased-restart called but not available, restarting normally." - return restart - end - true + @launcher.phased_restart end def redirect_io - @runner.redirect_io + @launcher.redirect_io end def stats @@ -259,8 +223,7 @@ module Puma end def halt - @status = :halt - @runner.halt + @launcher.halt end private @@ -269,15 +232,6 @@ module Puma raise UnsupportedOption end - def restart_args - cmd = @options[:restart_cmd] - if cmd - cmd.split(' ') + @original_argv - else - @restart_argv - end - end - # Build the OptionParser object to handle the available options. # @@ -412,55 +366,5 @@ module Puma end end end - - def generate_restart_data - # Use the same trick as unicorn, namely favor PWD because - # it will contain an unresolved symlink, useful for when - # the pwd is /data/releases/current. - if dir = ENV['PWD'] - s_env = File.stat(dir) - s_pwd = File.stat(Dir.pwd) - - if s_env.ino == s_pwd.ino and (jruby? or s_env.dev == s_pwd.dev) - @restart_dir = dir - @options[:worker_directory] = dir - end - end - - @restart_dir ||= Dir.pwd - - @original_argv = @argv.dup - - require 'rubygems' - - # if $0 is a file in the current directory, then restart - # it the same, otherwise add -S on there because it was - # picked up in PATH. - # - if File.exist?($0) - arg0 = [Gem.ruby, $0] - else - arg0 = [Gem.ruby, "-S", $0] - end - - # Detect and reinject -Ilib from the command line - lib = File.expand_path "lib" - arg0[1,0] = ["-I", lib] if $:[0] == lib - - if defined? Puma::WILD_ARGS - @restart_argv = arg0 + Puma::WILD_ARGS + @original_argv - else - @restart_argv = arg0 + @original_argv - end - end - - def close_binder_listeners - @binder.listeners.each do |l, io| - io.close - uri = URI.parse(l) - next unless uri.scheme == 'unix' - File.unlink("#{uri.host}#{uri.path}") - end - end end end diff --git a/lib/puma/detect.rb b/lib/puma/detect.rb index 8fa96499..c7ff99be 100644 --- a/lib/puma/detect.rb +++ b/lib/puma/detect.rb @@ -1,4 +1,11 @@ module Puma IS_JRUBY = defined?(JRUBY_VERSION) -end + def self.jruby? + IS_JRUBY + end + + def self.windows? + RUBY_PLATFORM =~ /mswin32|ming32/ + end +end diff --git a/lib/puma/launcher.rb b/lib/puma/launcher.rb index 10584104..54aee4af 100644 --- a/lib/puma/launcher.rb +++ b/lib/puma/launcher.rb @@ -34,6 +34,16 @@ module Puma @events end + # Delegate +error+ to +@events+ + # + def error(str) + @events.error str + end + + def debug(str) + @events.log "- #{str}" if @options[:debug] + end + def write_state write_pid @@ -74,11 +84,14 @@ module Puma end end - attr_accessor :options, :binder, :config, :events + attr_accessor :options, :binder, :config, :events, :argv ## THIS STUFF IS NEEDED FOR RUNNER + def setup(options) @options = options + generate_restart_data + parse_options dir = @options[:directory] @@ -101,7 +114,6 @@ module Puma end - attr_accessor :runner def stop @@ -139,13 +151,11 @@ module Puma end def jruby? - # remove eventually - IS_JRUBY + Puma.jruby? end def windows? - # remove eventually - RUBY_PLATFORM =~ /mswin32|ming32/ + Puma.windows? end @@ -176,6 +186,71 @@ module Puma end end + def redirect_io + @runner.redirect_io + end + + def phased_restart + unless @runner.respond_to?(:phased_restart) and @runner.phased_restart + log "* phased-restart called but not available, restarting normally." + return restart + end + true + end + + private + def restart_args + cmd = @options[:restart_cmd] + if cmd + cmd.split(' ') + @original_argv + else + @restart_argv + end + end + public + + + def jruby_daemon_start + require 'puma/jruby_restart' + JRubyRestart.daemon_start(@restart_dir, restart_args) + end + + def reload_worker_directory + @launcher.reload_worker_directory + end + + def restart! + @options[:on_restart].each do |block| + block.call self + end + + if jruby? + close_binder_listeners + + require 'puma/jruby_restart' + JRubyRestart.chdir_exec(@restart_dir, restart_args) + elsif windows? + close_binder_listeners + + argv = restart_args + Dir.chdir(@restart_dir) + argv += [redirects] if RUBY_VERSION >= '1.9' + Kernel.exec(*argv) + else + redirects = {:close_others => true} + @binder.listeners.each_with_index do |(l, io), i| + ENV["PUMA_INHERIT_#{i}"] = "#{io.to_i}:#{l}" + redirects[io.to_i] = io.to_i + end + + argv = restart_args + Dir.chdir(@restart_dir) + argv += [redirects] if RUBY_VERSION >= '1.9' + Kernel.exec(*argv) + end + end + + private def unsupported(str) @events.error(str) @@ -243,6 +318,57 @@ module Puma @options[:prune_bundler] && clustered? && !@options[:preload_app] end + def close_binder_listeners + @binder.listeners.each do |l, io| + io.close + uri = URI.parse(l) + next unless uri.scheme == 'unix' + File.unlink("#{uri.host}#{uri.path}") + end + end + + + def generate_restart_data + # Use the same trick as unicorn, namely favor PWD because + # it will contain an unresolved symlink, useful for when + # the pwd is /data/releases/current. + if dir = ENV['PWD'] + s_env = File.stat(dir) + s_pwd = File.stat(Dir.pwd) + + if s_env.ino == s_pwd.ino and (jruby? or s_env.dev == s_pwd.dev) + @restart_dir = dir + @options[:worker_directory] = dir + end + end + + @restart_dir ||= Dir.pwd + + @original_argv = @argv.nil? ? "puma" : @argv.dup + + require 'rubygems' + + # if $0 is a file in the current directory, then restart + # it the same, otherwise add -S on there because it was + # picked up in PATH. + # + if File.exist?($0) + arg0 = [Gem.ruby, $0] + else + arg0 = [Gem.ruby, "-S", $0] + end + + # Detect and reinject -Ilib from the command line + lib = File.expand_path "lib" + arg0[1,0] = ["-I", lib] if $:[0] == lib + + if defined? Puma::WILD_ARGS + @restart_argv = arg0 + Puma::WILD_ARGS + @original_argv + else + @restart_argv = arg0 + @original_argv + end + end + def setup_signals begin Signal.trap "SIGUSR2" do diff --git a/test/test_cli.rb b/test/test_cli.rb index 47cbbfe7..2a29351f 100644 --- a/test/test_cli.rb +++ b/test/test_cli.rb @@ -17,7 +17,7 @@ class TestCLI < Test::Unit::TestCase @wait, @ready = IO.pipe - @events = Events.strings + @events = Puma::Events.strings @events.on_booted { @ready << "!" } end