Skip to content

Commit

Permalink
Extracting runtime env bits into separate class
Browse files Browse the repository at this point in the history
  • Loading branch information
meatballhat committed Feb 18, 2014
1 parent 49bc40b commit 1a5212b
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 92 deletions.
79 changes: 21 additions & 58 deletions lib/resque/scheduler/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@

module Resque
module Scheduler
CLI_OPTIONS_ENV_MAPPING = {
app_name: 'APP_NAME',
background: 'BACKGROUND',
dynamic: 'DYNAMIC_SCHEDULE',
env: 'RAILS_ENV',
initializer_path: 'INITIALIZER_PATH',
logfile: 'LOGFILE',
logformat: 'LOGFORMAT',
quiet: 'QUIET',
pidfile: 'PIDFILE',
poll_sleep_amount: 'RESQUE_SCHEDULER_INTERVAL',
verbose: 'VERBOSE'
}

class Cli
BANNER = <<-EOF.gsub(/ {6}/, '')
Usage: resque-scheduler [options]
Expand Down Expand Up @@ -95,12 +109,8 @@ def pre_setup
end

def setup_env
require 'resque'
require 'resque/scheduler'

setup_backgrounding
setup_pid_file
setup_scheduler_configuration
require_relative 'env'
runtime_env.setup
end

def run_forever
Expand All @@ -111,6 +121,10 @@ def run_forever

attr_reader :argv, :env

def runtime_env
Resque::Scheduler::Env.new(options)
end

def option_parser
OptionParser.new do |opts|
opts.banner = BANNER
Expand All @@ -120,60 +134,9 @@ def option_parser
end
end

OPTIONS_ENV_MAPPING = {
app_name: 'APP_NAME',
background: 'BACKGROUND',
dynamic: 'DYNAMIC_SCHEDULE',
env: 'RAILS_ENV',
initializer_path: 'INITIALIZER_PATH',
logfile: 'LOGFILE',
logformat: 'LOGFORMAT',
quiet: 'QUIET',
pidfile: 'PIDFILE',
poll_sleep_amount: 'RESQUE_SCHEDULER_INTERVAL',
verbose: 'VERBOSE'
}

def options
@options ||= {}.tap do |o|
OPTIONS_ENV_MAPPING.map { |key, envvar| o[key] = env[envvar] }
end
end

def setup_backgrounding
# Need to set this here for conditional Process.daemon redirect of
# stderr/stdout to /dev/null
Resque::Scheduler.quiet = !!options[:quiet]

if options[:background]
unless Process.respond_to?('daemon')
abort 'background option is set, which requires ruby >= 1.9'
end

Process.daemon(true, !Resque::Scheduler.quiet)
Resque.redis.client.reconnect
end
end

def setup_pid_file
File.open(options[:pidfile], 'w') do |f|
f.puts $PROCESS_ID
end if options[:pidfile]
end

def setup_scheduler_configuration
Resque::Scheduler.configure do |c|
# These settings are somewhat redundant given the defaults present
# in the attr reader methods. They are left here for clarity and
# to serve as an example of how to use `.configure`.

c.app_name = options[:app_name]
c.dynamic = !!options[:dynamic]
c.env = options[:env]
c.logfile = options[:logfile]
c.logformat = options[:logformat]
c.poll_sleep_amount = Float(options[:poll_sleep_amount] || '5')
c.verbose = !!options[:verbose]
CLI_OPTIONS_ENV_MAPPING.map { |key, envvar| o[key] = env[envvar] }
end
end
end
Expand Down
61 changes: 61 additions & 0 deletions lib/resque/scheduler/env.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# vim:fileencoding=utf-8

module Resque
module Scheduler
class Env
def initialize(options)
@options = options
end

def setup
require 'resque'
require 'resque/scheduler'

setup_backgrounding
setup_pid_file
setup_scheduler_configuration
end

private

attr_reader :options

def setup_backgrounding
# Need to set this here for conditional Process.daemon redirect of
# stderr/stdout to /dev/null
Resque::Scheduler.quiet = !!options[:quiet]

if options[:background]
unless Process.respond_to?('daemon')
abort 'background option is set, which requires ruby >= 1.9'
end

Process.daemon(true, !Resque::Scheduler.quiet)
Resque.redis.client.reconnect
end
end

def setup_pid_file
File.open(options[:pidfile], 'w') do |f|
f.puts $PROCESS_ID
end if options[:pidfile]
end

def setup_scheduler_configuration
Resque::Scheduler.configure do |c|
# These settings are somewhat redundant given the defaults present
# in the attr reader methods. They are left here for clarity and
# to serve as an example of how to use `.configure`.

c.app_name = options[:app_name]
c.dynamic = !!options[:dynamic]
c.env = options[:env]
c.logfile = options[:logfile]
c.logformat = options[:logformat]
c.poll_sleep_amount = Float(options[:poll_sleep_amount] || '5')
c.verbose = !!options[:verbose]
end
end
end
end
end
41 changes: 7 additions & 34 deletions test/cli_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
require_relative 'test_helper'

context 'Cli' do
def mock_runtime_env
mock.tap { |m| m.stubs(:setup) }
end

def new_cli(argv = [], env = {})
Resque::Scheduler::Cli.new(argv, env)
Resque::Scheduler::Cli.new(argv, env).tap do |cli|
cli.stubs(:runtime_env).returns(mock_runtime_env)
end
end

test 'does not require any positional arguments' do
Expand Down Expand Up @@ -52,31 +58,6 @@ def new_cli(argv = [], env = {})
assert_equal(true, cli.send(:options)[:background])
end

test 'daemonizes when background is true' do
Process.expects(:daemon)
cli = new_cli(%w(--background))
cli.pre_run
end

test 'reconnects redis when background is true' do
Process.stubs(:daemon)
mock_redis_client = mock('redis_client')
mock_redis = mock('redis')
mock_redis.expects(:client).returns(mock_redis_client)
mock_redis_client.expects(:reconnect)
Resque.expects(:redis).returns(mock_redis)
cli = new_cli(%w(--background))
cli.pre_run
end

test 'aborts when background is given and Process does not support daemon' do
Process.stubs(:daemon)
Process.expects(:respond_to?).with('daemon').returns(false)
cli = new_cli(%w(--background))
cli.expects(:abort)
cli.pre_run
end

test 'initializes pidfile from the env' do
cli = new_cli([], 'PIDFILE' => 'bar')
assert_equal('bar', cli.send(:options)[:pidfile])
Expand All @@ -98,14 +79,6 @@ def new_cli(argv = [], env = {})
assert_equal('foo', cli.send(:options)[:pidfile])
end

test 'writes pid to pidfile when given' do
mock_pidfile = mock('pidfile')
mock_pidfile.expects(:puts)
File.expects(:open).with('derp.pid', 'w').yields(mock_pidfile)
cli = new_cli(%w(--pidfile derp.pid))
cli.pre_run
end

test 'defaults to nil dynamic' do
assert_equal(nil, new_cli.send(:options)[:dynamic])
end
Expand Down
41 changes: 41 additions & 0 deletions test/env_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# vim:fileencoding=utf-8
require_relative 'test_helper'

context 'Env' do
def new_env(options = {})
Resque::Scheduler::Env.new(options)
end

test 'daemonizes when background is true' do
Process.expects(:daemon)
env = new_env(background: true)
env.setup
end

test 'reconnects redis when background is true' do
Process.stubs(:daemon)
mock_redis_client = mock('redis_client')
mock_redis = mock('redis')
mock_redis.expects(:client).returns(mock_redis_client)
mock_redis_client.expects(:reconnect)
Resque.expects(:redis).returns(mock_redis)
env = new_env(background: true)
env.setup
end

test 'aborts when background is given and Process does not support daemon' do
Process.stubs(:daemon)
Process.expects(:respond_to?).with('daemon').returns(false)
env = new_env(background: true)
env.expects(:abort)
env.setup
end

test 'writes pid to pidfile when given' do
mock_pidfile = mock('pidfile')
mock_pidfile.expects(:puts)
File.expects(:open).with('derp.pid', 'w').yields(mock_pidfile)
env = new_env(pidfile: 'derp.pid')
env.setup
end
end

0 comments on commit 1a5212b

Please sign in to comment.