From 76cc068d8aa8716fec47d51b415160ce935f8f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Tue, 26 Mar 2013 22:31:09 +0100 Subject: [PATCH] Change and cleanup config Beside redis connection, all Resque configuration is needed only for worker class which is dispatched from CLI. This means the we actually don't need to keep this in class, it's was only there because of ENV support which is now solved in a different way, directly in Rake task. Defaults from config and CLI class were removed, there was no sense to set it in so many places. Worker's constructor is the place were default options for it should be set. Removed #load_config method, moved it's logic to CLI#initialize. CLI class, especially #work method, is much cleaner now. --- lib/resque/cli.rb | 56 +++++++++++++++++--------------------- lib/resque/config.rb | 43 ++--------------------------- lib/resque/tasks.rb | 20 ++++++++++++-- lib/resque/worker.rb | 14 ++++++++-- test/fixtures/resque.yml | 8 ++++++ test/resque/cli_test.rb | 14 ++++++++++ test/resque/config_test.rb | 54 ------------------------------------ 7 files changed, 78 insertions(+), 131 deletions(-) create mode 100644 test/fixtures/resque.yml create mode 100644 test/resque/cli_test.rb diff --git a/lib/resque/cli.rb b/lib/resque/cli.rb index 5df356ae3..0ade90dd1 100644 --- a/lib/resque/cli.rb +++ b/lib/resque/cli.rb @@ -1,3 +1,4 @@ +require 'yaml' require 'thor' require "resque" @@ -7,42 +8,47 @@ class CLI < Thor class_option :redis, :aliases => ["-R"], :type => :string class_option :namespace, :aliases => ["-N"], :type => :string + def initialize(args = [], opts = [], config = {}) + super(args, opts, config) + + if options[:config] && File.exists?(options[:config]) + @options = YAML.load_file(options[:config]).symbolize_keys.merge(@options.symbolize_keys) + end + end + desc "work", "Start processing jobs." - option :queues, :aliases => ["-q"], :type => :string, :default => "*" - option :requirement,:aliases => ["-r"], :type => :string, :default => "." - option :pid, :aliases => ["-p"], :type => :string - option :interval, :aliases => ["-i"], :type => :numeric, :default => 5 - option :daemon, :aliases => ["-d"], :type => :boolean, :default => false - option :timeout, :aliases => ["-t"], :type => :numeric, :default => 4.0 + option :queues, :aliases => ["-q"], :type => :string + option :require, :aliases => ["-r"], :type => :string + option :pid_file, :aliases => ["-p"], :type => :string + option :interval, :aliases => ["-i"], :type => :numeric + option :daemon, :aliases => ["-d"], :type => :boolean + option :timeout, :aliases => ["-t"], :type => :numeric + option :fork_per_job, :aliases => ["-f"], :type => :boolean def work - load_config + load_enviroment(options[:require]) - load_enviroment(Resque.config.require) + queues = options[:queues].to_s.split(',') + opts = @options.symbolize_keys.slice(:timeout, :interval, :daemon, :pid_file) - worker = Resque::Worker.new(Resque.config.queues, Resque.config.options.slice(:timeout, :interval, :daemon, :pid)) - worker.work + Resque::Worker.new(queues, opts).work end desc "workers", "Start multiple Resque workers. Should only be used in dev mode." option :count, :aliases => ["-n"], :type => :numeric, :default => 5 def workers - load_config - threads = [] - Resque.config.count.to_i.times do + options[:count].to_i.times do threads << Thread.new do self.work end end - threads.each { |thread| thread.join } + threads.each(&:join) end desc "kill WORKER", "Kills a worker" def kill(worker) - load_config - pid = worker.split(':')[1].to_i begin @@ -57,16 +63,12 @@ def kill(worker) desc "remove WORKER", "Removes a worker" def remove(worker) - load_config - Resque.remove_worker(worker) puts "Removed #{worker}" end desc "list", "Lists known workers" def list - load_config - if Resque.workers.any? Resque.workers.each do |worker| puts "#{worker} (#{worker.state})" @@ -79,7 +81,6 @@ def list desc "sort_failures", "Sort the 'failed' queue for the redis_multi_queue failure backend" def sort_failures require 'resque/failure/redis' - load_config warn "Sorting #{Resque::Failure.count} failures..." Resque::Failure.each(0, Resque::Failure.count) do |_, failure| @@ -89,19 +90,11 @@ def sort_failures warn "done!" end - protected - - def load_config - opts = {} - if options[:config] - opts = YAML.load_file(File.expand_path(options[:config])) - end - Resque.config = opts.merge!(options) - end + protected def load_enviroment(file = nil) - return if file.nil? + file ||= "." if File.directory?(file) && File.exists?(File.expand_path("#{file}/config/environment.rb")) require "rails" @@ -118,5 +111,6 @@ def load_enviroment(file = nil) require File.expand_path(file) end end + end end diff --git a/lib/resque/config.rb b/lib/resque/config.rb index c616b8d68..b3d5665f9 100644 --- a/lib/resque/config.rb +++ b/lib/resque/config.rb @@ -5,48 +5,11 @@ class Config attr_accessor :options def initialize(options = {}) - @options = { - :daemon => env(:background) || false, - :count => env(:count) || 5, - :failure_backend => env(:failure_backend) || "redis", - :fork_per_job => env(:fork_per_job).nil? || env(:fork_per_job) == "true", - :interval => env(:interval) || 5, - :pid => env(:pid_file) || nil, - :queues => (env(:queue) || env(:queues) || "*"), - :timeout => env(:rescue_term_timeout) || 4.0, - :requirement => nil - }.merge!(options.symbolize_keys!) + @options = options end - def timeout - @options[:timeout].to_f + def failure_backend + "redis" end - - def interval - @options[:interval].to_i - end - - def queues - @options[:queues].to_s.split(',') - end - - def method_missing(name) - name = name.to_sym - if @options.has_key?(name) - @options[name] - end - end - - protected - - def env(key) - key = key.to_s.upcase - if ENV.key?(key) - Kernel.warn "DEPRECATION WARNING: Using ENV variables is deprecated and will be removed in Resque 2.1" - ENV[key] - else - nil - end - end end end diff --git a/lib/resque/tasks.rb b/lib/resque/tasks.rb index b7d70f676..55238287e 100644 --- a/lib/resque/tasks.rb +++ b/lib/resque/tasks.rb @@ -8,13 +8,27 @@ desc "Start a Resque worker" task :work => [ :preload, :setup ] do puts "DEPRECATION WARNING: Rake tasks are depreacted. Use `resque work` instead" - Resque::CLI.new.work + + opts = [ + "-q", ENV['QUEUES'] || ENV['QUEUE'] || "*", + "-t", ENV['RESQUE_TERM_TIMEOUT'] || 4.0, + "-d", !ENV['BACKGROUND'].nil?, + "-p", ENV['PIDFILE'], + "-i", ENV['INTERVAL'] || 5 + ] + + Resque::CLI.new([], opts).invoke(:work) end desc "Start multiple Resque workers. Should only be used in dev mode." task :workers do puts "DEPRECATION WARNING: Rake tasks are depreacted. Use `resque workers` instead" - Resque::CLI.new.workers + + opts = [ + "-n", ENV['COUNT'] || 5 + ] + + Resque::CLI.new([], opts).invoke(:workers) end # Preload app files if this is Rails @@ -33,7 +47,7 @@ desc "Sort the 'failed' queue for the redis_multi_queue failure backend" task :sort do puts "DEPRECATION WARNING: Rake tasks are depreacted. Use `resque sort_failures` instead" - Resque::CLI.new.sort_failures + Resque::CLI.new.invoke(:sort_failures) end end end \ No newline at end of file diff --git a/lib/resque/worker.rb b/lib/resque/worker.rb index 293332489..f2ee21dd4 100644 --- a/lib/resque/worker.rb +++ b/lib/resque/worker.rb @@ -90,7 +90,15 @@ def self.constantize(camel_cased_word) # in alphabetical order. Queues can be dynamically added or # removed without needing to restart workers using this method. def initialize(queues = [], options = {}) - @options = { :timeout => 0, :interval => 0, :daemon => false, :pid => nil }.merge(options.symbolize_keys) + @options = { + :timeout => 0, + :interval => 0, + :daemon => false, + :pid_file => nil, + :fork_per_job => true, + } + @options.merge!(options.symbolize_keys) + @queues = (queues.is_a?(Array) ? queues : [queues]).map { |queue| queue.to_s.strip } @shutdown = nil @paused = nil @@ -365,7 +373,7 @@ def fork(job,&block) def startup procline "Starting" daemonize if options[:daemonize] - pid_file(options[:pid]) if options[:pid] + pid_file(options[:pid_file]) if options[:pid_file] enable_gc_optimizations register_signal_handlers prune_dead_workers @@ -449,7 +457,7 @@ def failed! end def will_fork? - !@cant_fork && Resque.config.fork_per_job + !@cant_fork && !$TESTING && options[:fork_per_job] end # Given a string, sets the procline ($0) and logs. diff --git a/test/fixtures/resque.yml b/test/fixtures/resque.yml new file mode 100644 index 000000000..bb13f07af --- /dev/null +++ b/test/fixtures/resque.yml @@ -0,0 +1,8 @@ +redis: "" +namespace: "" +failure_backed: "" +daemon: true +failure_backend: "redis" +fork_per_job: true +interval: 1 +timeout: 2 \ No newline at end of file diff --git a/test/resque/cli_test.rb b/test/resque/cli_test.rb new file mode 100644 index 000000000..98fc96629 --- /dev/null +++ b/test/resque/cli_test.rb @@ -0,0 +1,14 @@ +require 'test_helper' + +require 'resque/cli' + +describe Resque::CLI do + it "#work" do + cli = Resque::CLI.new([], ["-c", "test/fixtures/resque.yml", "-i", "666", "-q", "first,second", "-r", "path/to/file"]) + w = mock("Resque::Worker") + w.expects(:work) + Resque::Worker.expects(:new).with(["first", "second"], {:timeout => 2, :interval => 666, :daemon => true}).returns(w) + Resque::CLI.any_instance.expects(:load_enviroment).with("path/to/file") + cli.invoke(:work) + end +end diff --git a/test/resque/config_test.rb b/test/resque/config_test.rb index 827c7ee6c..71786e030 100644 --- a/test/resque/config_test.rb +++ b/test/resque/config_test.rb @@ -3,58 +3,4 @@ require 'resque/config' describe Resque::Config do - it "defaults" do - defaults = { - :daemon => false, - :count => 5, - :failure_backend => "redis", - :fork_per_job => true, - :interval => 5, - :pid => nil, - :queues => "*", - :timeout => 4.0, - :requirement => nil - } - - assert_equal defaults, Resque::Config.new.options - end - - it "return config var from ENV if set" do - begin - ENV["QUEUES"] = "high,failure" - - silence_warnings do - config = Resque::Config.new - assert_equal config.queues, ["high", "failure"] - end - ensure - ENV.delete("QUEUES") - end - end - - it "return config var from file (should overwrite ENV)" do - begin - ENV["QUEUES"] = "low,archive" - - silence_warnings do - config = Resque::Config.new({ "queue" => "low,archive" }) - assert_equal config.queues, ["low", "archive"] - end - ensure - ENV.delete("QUEUES") - end - end - - it "method missing" do - config = Resque::Config.new(:foo => "bar") - assert_equal config.options[:foo], "bar" - assert_equal config.foo, "bar" - end - - it "interval & time should be floats" do - config = Resque::Config.new(:interval => "1", :timeout => "2") - - assert_equal config.interval, 1.0 - assert_equal config.timeout, 2.0 - end end