daemonize option to launch the server

did committed Jan 16, 2014
commit 6597a6943abb0528b3da39743217de12905d449e
Showing 5 changed files with 73 additions and 24 deletions
locomotive/wagon.rb b/lib/locomotive/wagon.rb +32 -8
@@ @@ -28,21 +28,45 @@ module Locomotive
require 'locomotive/wagon/server'
app = Locomotive::Wagon::Server.new(reader)
+ use_listen = !options[:disable_listen]
+
+ # TODO: new feature -> pick the right Rack handler (Thin, Puma, ...etc)
require 'thin'
- server = Thin::Server.new(options[:host], options[:port], app)
- server.threaded = true # TODO: make it an option ?
- server.start
+ server = Thin::Server.new(options[:host], options[:port], app)
+ server.threaded = true
+
+ if options[:force]
+ begin
+ self.stop(path)
+ sleep(2) # make sure we wait enough for the Thin process to stop
+ rescue
+ end
+ end
+
+ if options[:daemonize]
+ # very important to get the parent pid in order to differenciate the sub process from the parent one
+ parent_pid = Process.pid
+
+ server.log_file = File.join(File.expand_path(path), 'log', 'thin.log')
+ server.pid_file = File.join(File.expand_path(path), 'log', 'thin.pid')
+ server.daemonize
- # require 'unicorn' # TODO: gem 'unicorn'
- # server = Unicorn::HttpServer.new(app)
- # server.start
+ use_listen = Process.pid != parent_pid && !options[:disable_listen]
+ end
+
+ Locomotive::Wagon::Listen.instance.start(reader) if use_listen
- # require 'rack'
- # Rack::Handler::WEBrick.run(app, { :'Port' => options[:port], :'Host' => options[:host] })
+ server.start
end
end
+ def self.stop(path)
+ pid_file = File.join(File.expand_path(path), 'log', 'thin.pid')
+ pid = File.read(pid_file).to_i
+ Process.kill('TERM', pid)
+ end
+
# Generate components for the LocomotiveCMS site such as content types, snippets, pages.
#
# @param [ Symbol ] name The name of the generator
locomotive/wagon/cli.rb b/lib/locomotive/wagon/cli.rb +30 -8
@@ @@ -124,13 +124,13 @@ module Locomotive
class_option :force_color, aliases: '-c', type: :boolean, default: false, desc: 'Whether or not to use ANSI color in the output.'
- desc 'version', 'Version of the LocomotiveCMS wagon'
+ desc 'version', 'Version of the LocomotiveCMS Wagon'
def version
require 'locomotive/wagon/version'
say Locomotive::Wagon::VERSION
end
- desc 'init NAME [PATH] [OPTIONS]', 'Create a brand new LocomotiveCMS site'
+ desc 'init NAME [PATH] [OPTIONS]', 'Create a brand new site'
method_option :template, aliases: '-t', type: 'string', default: 'blank', desc: 'instead of building from a blank site, you can have a pre-fetched site with form a template (see the templates command)'
method_option :lib, aliases: '-l', type: 'string', desc: 'Path to an external ruby lib or generator'
method_option :skip_bundle, type: 'boolean', default: false, desc: "Don't run bundle install"
@@ @@ -177,7 +177,6 @@ module Locomotive
method_option :lib, aliases: '-l', type: 'string', desc: 'Path to an external ruby lib or generator'
method_option :json, aliases: '-j', type: :boolean, default: false, desc: 'Output the list in JSON'
def list_templates
- puts Gem.ruby
force_color_if_asked(options)
require 'locomotive/wagon/generators/site'
require File.expand_path(options[:lib]) if options[:lib]
@@ @@ -193,13 +192,36 @@ module Locomotive
end
end
- desc 'serve [PATH]', 'Serve a LocomotiveCMS site from the file system'
+ desc 'serve [PATH]', 'Serve a site from the file system'
method_option :host, aliases: '-h', type: 'string', default: '0.0.0.0', desc: 'The host (address) of the Thin server'
method_option :port, aliases: '-p', type: 'string', default: '3333', desc: 'The port of the Thin server'
+ method_option :daemonize, aliases: '-d', type: 'boolean', default: false, desc: 'Run daemonized Thin server in the background'
+ method_option :force, aliases: '-f', type: 'boolean', default: false, desc: 'Stop the current daemonized Thin server if found before starting a new one'
+ method_option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
def serve(path = '.')
+ parent_pid = Process.pid
+ force_color_if_asked(options)
if check_path!(path)
begin
Locomotive::Wagon.serve(path, options)
+ rescue SystemExit => e
+ if parent_pid == Process.pid
+ say "Your site is served now.", :green
+ end
+ rescue Exception => e
+ self.print_exception(e, options[:verbose])
+ exit(1)
+ end
+ end
+ end
+
+ desc 'stop [PATH]', 'Stop serving a site previously launched by the serve command with the -d option'
+ def stop(path = '.')
+ force_color_if_asked(options)
+ if check_path!(path)
+ begin
+ Locomotive::Wagon.stop(path)
+ say "Your site is not served anymore.", :green
rescue Exception => e
say e.message, :red
exit(1)
@@ @@ -207,7 +229,7 @@ module Locomotive
end
end
- desc 'push ENV [PATH]', 'Push a site to a remote LocomotiveCMS engine'
+ desc 'push ENV [PATH]', 'Push a site to a remote LocomotiveCMS Engine'
method_option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only push the resource(s) passed in argument'
method_option :force, aliases: '-f', type: 'boolean', default: false, desc: 'Force the push of a resource'
method_option :translations, aliases: '-t', type: 'boolean', default: false, desc: 'Push the local translations (by default, they are not)'
@@ @@ -226,7 +248,7 @@ module Locomotive
end
end
- desc 'pull ENV [PATH]', 'Pull a site from a remote LocomotiveCMS engine'
+ desc 'pull ENV [PATH]', 'Pull a site from a remote LocomotiveCMS Engine'
method_option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only pull the resource(s) passed in argument'
method_option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
def pull(env, path = '.')
@@ @@ -242,7 +264,7 @@ module Locomotive
end
end
- desc 'destroy ENV [PATH]', 'Destroy a remote LocomotiveCMS engine'
+ desc 'destroy ENV [PATH]', 'Destroy a remote LocomotiveCMS Engine'
def destroy(env, path = '.')
if check_path!(path)
if connection_info = self.retrieve_connection_info(env, path)
@@ @@ -281,7 +303,7 @@ module Locomotive
# @param [ Boolean ] verbose Print the full backtrace if true
#
def print_exception(exception, verbose)
- say exception.message, :red
+ say exception.message + Process.pid.to_s, :red
if verbose
say "\t" + exception.backtrace.join("\n\t")
end
locomotive/wagon/listen.rb b/lib/locomotive/wagon/listen.rb +9 -2
@@ @@ -10,6 +10,13 @@ module Locomotive::Wagon
end
def start(reader)
+ # if $parent_pid && $parent_pid == Process.pid
+ # puts "bypassing Listen in the parent process"
+ # return false
+ # end
+
+ puts "Listening here: #{Process.pid}"
+
self.reader = reader
self.definitions.each do |definition|
@@ @@ -46,10 +53,10 @@ module Locomotive::Wagon
path = File.join(self.reader.mounting_point.path, definition.first)
path = File.expand_path(path)
- listener = ::Listen.to(path).filter(filter).change(&reloader)
+ listener = ::Listen.to(path, only: filter, &reloader)
# non blocking listener
- listener.start(false)
+ listener.start #(false)
end
end
locomotive/wagon/server.rb b/lib/locomotive/wagon/server.rb +0 -4
@@ @@ -26,10 +26,6 @@ module Locomotive::Wagon
@reader = reader
@app = self.create_rack_app(@reader)
- unless options[:disable_listen]
- Locomotive::Wagon::Listen.instance.start(@reader)
- end
-
BetterErrors.application_root = reader.mounting_point.path
end
locomotivecms_wagon.gemspec +2 -2
@@ @@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
gem.executables = ['wagon']
gem.add_dependency 'thor'
- gem.add_dependency 'thin', '~> 1.5.1'
+ gem.add_dependency 'thin', '~> 1.6.1'
gem.add_dependency 'activesupport', '~> 3.2.11'
gem.add_dependency 'locomotivecms-solid', '~> 0.2.2.1'
gem.add_dependency 'RedCloth', '~> 4.2.8'
@@ @@ -31,7 +31,7 @@ Gem::Specification.new do |gem|
gem.add_dependency 'better_errors', '~> 1.0.1'
gem.add_dependency 'rubyzip', '~> 1.1.0'
- gem.add_dependency 'listen', '~> 0.7.0'
+ gem.add_dependency 'listen', '~> 2.4.0'
gem.add_dependency 'httmultiparty', '0.3.10'
gem.add_dependency 'will_paginate', '~> 3.0.3'