add start|stop|restart|run to crono executable

this is done using daemonize gem, but it is not breaking the old
interface. But sets a deprected comment to the old one daemonize
process.
This commit is contained in:
Jannis Hübl
2016-01-15 11:03:38 +01:00
parent 6881109934
commit 0affff21d1
6 changed files with 165 additions and 19 deletions

View File

@@ -26,6 +26,7 @@ GEM
byebug (5.0.0) byebug (5.0.0)
columnize (= 0.9.0) columnize (= 0.9.0)
columnize (0.9.0) columnize (0.9.0)
daemons (1.2.2)
diff-lcs (1.2.5) diff-lcs (1.2.5)
haml (4.0.6) haml (4.0.6)
tilt tilt
@@ -69,6 +70,7 @@ DEPENDENCIES
bundler (>= 1.0.0) bundler (>= 1.0.0)
byebug byebug
crono! crono!
daemons
haml haml
rack-test rack-test
rake (~> 10.0) rake (~> 10.0)
@@ -76,6 +78,3 @@ DEPENDENCIES
sinatra sinatra
sqlite3 sqlite3
timecop (~> 0.7) timecop (~> 0.7)
BUNDLED WITH
1.10.6

View File

@@ -30,4 +30,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'sinatra' spec.add_development_dependency 'sinatra'
spec.add_development_dependency 'haml' spec.add_development_dependency 'haml'
spec.add_development_dependency 'rack-test' spec.add_development_dependency 'rack-test'
spec.add_development_dependency 'daemons'
end end

View File

@@ -7,6 +7,8 @@ module Crono
include Singleton include Singleton
include Logging include Logging
COMMANDS = %w(start stop restart run zap reload status)
attr_accessor :config attr_accessor :config
def initialize def initialize
@@ -16,16 +18,21 @@ module Crono
def run def run
parse_options(ARGV) parse_options(ARGV)
parse_command(ARGV)
setup_log setup_log
write_pid write_pid unless config.daemonize
load_rails load_rails
Cronotab.process(File.expand_path(config.cronotab)) Cronotab.process(File.expand_path(config.cronotab))
print_banner print_banner
check_jobs check_jobs
start_working_loop if config.daemonize
start_working_loop_in_daemon
else
start_working_loop
end
end end
private private
@@ -33,13 +40,15 @@ module Crono
def setup_log def setup_log
if config.daemonize if config.daemonize
self.logfile = config.logfile self.logfile = config.logfile
daemonize elsif config.deprecated_daemonize
self.logfile = config.logfile
deprecated_daemonize
else else
self.logfile = STDOUT self.logfile = STDOUT
end end
end end
def daemonize def deprecated_daemonize
::Process.daemon(true, true) ::Process.daemon(true, true)
[$stdout, $stderr].each do |io| [$stdout, $stderr].each do |io|
@@ -71,7 +80,7 @@ module Crono
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = config.environment ENV['RACK_ENV'] = ENV['RAILS_ENV'] = config.environment
require 'rails' require 'rails'
require File.expand_path('config/environment.rb') require File.expand_path('config/environment.rb')
::Rails.application.eager_load! ::Rails.application.eager_load! if config.daemonize
end end
def check_jobs def check_jobs
@@ -79,6 +88,30 @@ module Crono
logger.error "You have no jobs in you cronotab file #{config.cronotab}" logger.error "You have no jobs in you cronotab file #{config.cronotab}"
end end
def start_working_loop_in_daemon
unless ENV['RAILS_ENV'] == 'test'
begin
require 'daemons'
rescue LoadError
raise "You need to add gem 'daemons' to your Gemfile if you wish to use it."
end
end
Daemons.run_proc(config.process_name, dir: config.piddir, dir_mode: :normal, monitor: config.monitor, ARGV: @argv) do |*_argv|
Dir.chdir(root)
Crono.logger = Logger.new(config.logfile)
start_working_loop
end
end
def root
@root ||= rails_root_defined? ? ::Rails.root : DIR_PWD
end
def rails_root_defined?
defined?(::Rails.root)
end
def start_working_loop def start_working_loop
loop do loop do
next_time, jobs = Crono.scheduler.next_jobs next_time, jobs = Crono.scheduler.next_jobs
@@ -88,8 +121,8 @@ module Crono
end end
def parse_options(argv) def parse_options(argv)
OptionParser.new do |opts| @argv = OptionParser.new do |opts|
opts.banner = "Usage: crono [options]" opts.banner = "Usage: crono [options] start|stop|restart|run"
opts.on("-C", "--cronotab PATH", "Path to cronotab file (Default: #{config.cronotab})") do |cronotab| opts.on("-C", "--cronotab PATH", "Path to cronotab file (Default: #{config.cronotab})") do |cronotab|
config.cronotab = cronotab config.cronotab = cronotab
@@ -103,8 +136,20 @@ module Crono
config.pidfile = pidfile config.pidfile = pidfile
end end
opts.on("-d", "--[no-]daemonize", "Daemonize process (Default: #{config.daemonize})") do |daemonize| opts.on("--piddir PATH", "Path to piddir (Default: #{config.piddir})") do |piddir|
config.daemonize = daemonize config.piddir = piddir
end
opts.on("-N", "--process_name name", "Name of the process (Default: #{config.process_name})") do |process_name|
config.process_name = process_name
end
opts.on("-d", "--[no-]daemonize", "Deprecated! Instead use crono [start|stop|restart] without this option; Daemonize process (Default: #{config.daemonize})") do |daemonize|
config.deprecated_daemonize = daemonize
end
opts.on("-m", "--monitor", "Start monitor process for a deamon (Default #{config.monitor})") do
config.monitor = true
end end
opts.on '-e', '--environment ENV', "Application environment (Default: #{config.environment})" do |env| opts.on '-e', '--environment ENV', "Application environment (Default: #{config.environment})" do |env|
@@ -112,5 +157,12 @@ module Crono
end end
end.parse!(argv) end.parse!(argv)
end end
def parse_command(argv)
if COMMANDS.include? argv[0]
config.daemonize = true
end
end
end end
end end

View File

@@ -4,18 +4,31 @@ module Crono
CRONOTAB = 'config/cronotab.rb' CRONOTAB = 'config/cronotab.rb'
LOGFILE = 'log/crono.log' LOGFILE = 'log/crono.log'
PIDFILE = 'tmp/pids/crono.pid' PIDFILE = 'tmp/pids/crono.pid'
PIDDIR = 'tmp/pids'
PROCESS_NAME = 'crono'
attr_accessor :cronotab, :logfile, :pidfile, :daemonize, :environment attr_accessor :cronotab, :logfile, :pidfile, :piddir, :process_name,
:monitor, :daemonize, :deprecated_daemonize, :environment
def initialize def initialize
self.cronotab = CRONOTAB self.cronotab = CRONOTAB
self.logfile = LOGFILE self.logfile = LOGFILE
self.piddir = PIDDIR
self.process_name = PROCESS_NAME
self.daemonize = false self.daemonize = false
self.deprecated_daemonize = false
self.monitor = false
self.environment = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development' self.environment = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
end end
def pidfile=(pidfile)
@pidfile = pidfile
self.process_name = Pathname.new(pidfile).basename(".*").to_s
self.piddir = Pathname.new(pidfile).dirname.to_s
end
def pidfile def pidfile
@pidfile || (daemonize ? PIDFILE : nil) @pidfile || (deprecated_daemonize ? PIDFILE : nil)
end end
end end
end end

View File

@@ -9,10 +9,25 @@ describe Crono::CLI do
expect(cli).to receive(:load_rails) expect(cli).to receive(:load_rails)
expect(cli).to receive(:start_working_loop) expect(cli).to receive(:start_working_loop)
expect(cli).to receive(:parse_options) expect(cli).to receive(:parse_options)
expect(cli).to receive(:parse_command)
expect(cli).to receive(:write_pid) expect(cli).to receive(:write_pid)
expect(Crono::Cronotab).to receive(:process) expect(Crono::Cronotab).to receive(:process)
cli.run cli.run
end end
context 'should run as daemon' do
before {cli.config.daemonize = true}
it 'should initialize rails with #load_rails and start working loop' do
expect(cli).to receive(:load_rails)
expect(cli).to receive(:start_working_loop_in_daemon)
expect(cli).to receive(:parse_options)
expect(cli).to receive(:parse_command)
expect(cli).not_to receive(:write_pid)
expect(Crono::Cronotab).to receive(:process)
cli.run
end
end
end end
describe '#parse_options' do describe '#parse_options' do
@@ -31,9 +46,24 @@ describe Crono::CLI do
expect(cli.config.pidfile).to be_eql 'tmp/pids/crono.0.log' expect(cli.config.pidfile).to be_eql 'tmp/pids/crono.0.log'
end end
it 'should set daemonize' do it 'should set piddir' do
cli.send(:parse_options, ['--piddir', 'tmp/pids'])
expect(cli.config.piddir).to be_eql 'tmp/pids'
end
it 'should set process_name' do
cli.send(:parse_options, ['--process_name', 'crono0'])
expect(cli.config.process_name).to be_eql 'crono0'
end
it 'should set monitor' do
cli.send(:parse_options, ['--monitor'])
expect(cli.config.monitor).to be true
end
it 'should set deprecated_daemonize' do
cli.send(:parse_options, ['--daemonize']) cli.send(:parse_options, ['--daemonize'])
expect(cli.config.daemonize).to be true expect(cli.config.deprecated_daemonize).to be true
end end
it 'should set environment' do it 'should set environment' do
@@ -41,4 +71,42 @@ describe Crono::CLI do
expect(cli.config.environment).to be_eql('production') expect(cli.config.environment).to be_eql('production')
end end
end end
describe '#parse_command' do
it 'should set daemonize on start' do
cli.send(:parse_command, ['start'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on stop' do
cli.send(:parse_command, ['stop'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on restart' do
cli.send(:parse_command, ['restart'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on run' do
cli.send(:parse_command, ['run'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on zap' do
cli.send(:parse_command, ['zap'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on reload' do
cli.send(:parse_command, ['reload'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on status' do
cli.send(:parse_command, ['status'])
expect(cli.config.daemonize).to be true
end
end
end end

View File

@@ -9,7 +9,11 @@ describe Crono::Config do
expect(@config.cronotab).to be Crono::Config::CRONOTAB expect(@config.cronotab).to be Crono::Config::CRONOTAB
expect(@config.logfile).to be Crono::Config::LOGFILE expect(@config.logfile).to be Crono::Config::LOGFILE
expect(@config.pidfile).to be nil expect(@config.pidfile).to be nil
expect(@config.piddir).to be Crono::Config::PIDDIR
expect(@config.process_name).to be Crono::Config::PROCESS_NAME
expect(@config.daemonize).to be false expect(@config.daemonize).to be false
expect(@config.deprecated_daemonize).to be false
expect(@config.monitor).to be false
expect(@config.environment).to be_eql ENV['RAILS_ENV'] expect(@config.environment).to be_eql ENV['RAILS_ENV']
end end
@@ -23,8 +27,8 @@ describe Crono::Config do
specify { expect(pidfile).to be_nil } specify { expect(pidfile).to be_nil }
end end
context "daemonize is true" do context "deprecated_daemonize is true" do
before { config.daemonize = true } before { config.deprecated_daemonize = true }
specify { expect(pidfile).to eq Crono::Config::PIDFILE } specify { expect(pidfile).to eq Crono::Config::PIDFILE }
end end
@@ -36,7 +40,16 @@ describe Crono::Config do
before { config.pidfile = path } before { config.pidfile = path }
specify { expect(pidfile).to eq path } specify { expect(pidfile).to eq path }
it "trys to set piddir" do
expect(config.piddir).to eq "foo/bar"
end
it "trys to set process_name" do
expect(config.process_name).to eq "pid"
end
end end
end end
end end
end end