From d9593edc58a06f6b9899b77825a08d6d3e87b1d2 Mon Sep 17 00:00:00 2001 From: AMHOL Date: Thu, 1 Apr 2021 16:58:49 +0800 Subject: [PATCH] Add ActiveScheduler.config.{guard_with,queue_name_resolver} This allows configuration of a custom guard clause to check whether jobs should be wrapped or not, as well as allowing for a custom queue_name_resolver configuration which will be called to resolve the queue name when the queue is not configured. The idea behind this is to enable an option which avoids the use of "class_name.constantize", meaning that we don't have to load the entire Rails environment for the resque scheduler rake task and save some memory. --- lib/active_scheduler.rb | 16 ++++ lib/active_scheduler/resque_wrapper.rb | 6 +- spec/active_scheduler/resque_wrapper_spec.rb | 88 ++++++++++++++++---- spec/spec_helper.rb | 4 +- 4 files changed, 93 insertions(+), 21 deletions(-) diff --git a/lib/active_scheduler.rb b/lib/active_scheduler.rb index fba9fef..f2b75af 100644 --- a/lib/active_scheduler.rb +++ b/lib/active_scheduler.rb @@ -3,5 +3,21 @@ require 'active_scheduler/resque_wrapper' module ActiveScheduler + Config = Struct.new(:guard_with, :queue_name_resolver) + class << self + def config + @config ||= Config.new + end + + def configure(&block) + yield(config) + end + end + + # Default config + configure do |config| + config.guard_with = ->(class_name) { class_name.constantize <= ActiveJob::Base } + config.queue_name_resolver = ->(class_name) { class_name.constantize.queue_name } + end end diff --git a/lib/active_scheduler/resque_wrapper.rb b/lib/active_scheduler/resque_wrapper.rb index e88dd6b..b784160 100644 --- a/lib/active_scheduler/resque_wrapper.rb +++ b/lib/active_scheduler/resque_wrapper.rb @@ -28,11 +28,9 @@ def self.wrap(schedule) schedule.each do |job, opts| class_name = opts[:class] || job next if class_name =~ /#{self.to_s}/ + next unless ActiveScheduler.config.guard_with.(class_name) - klass = class_name.constantize - next unless klass <= ActiveJob::Base - - queue = opts[:queue] || klass.queue_name + queue = opts[:queue] || ActiveScheduler.config.queue_name_resolver.(class_name) args = opts[:args] named_args = opts[:named_args] || false diff --git a/spec/active_scheduler/resque_wrapper_spec.rb b/spec/active_scheduler/resque_wrapper_spec.rb index d56c4de..55d2466 100644 --- a/spec/active_scheduler/resque_wrapper_spec.rb +++ b/spec/active_scheduler/resque_wrapper_spec.rb @@ -25,16 +25,48 @@ end context "job is not an active job descendant" do - it "doesn't wrap" do - stub_const("SimpleJob", Class.new) - expect(wrapped['simple_job']).to eq( - "class" => "SimpleJob", - "queue" => "simple", - "description" => "It's a simple job.", - "every" => "30s", - "rails_env" => "test", - "args" => ['foo-arg-1', 'foo-arg-2'], - ) + context "with default configuration" do + it "doesn't wrap" do + stub_jobs("SimpleJob", base_class: Class.new) + expect(wrapped['simple_job']).to eq( + "class" => "SimpleJob", + "queue" => "simple", + "description" => "It's a simple job.", + "every" => "30s", + "rails_env" => "test", + "args" => ['foo-arg-1', 'foo-arg-2'], + ) + end + end + + context "with a custom guard_with configuration" do + let!(:guard_with) do + ActiveScheduler.config.guard_with + end + + before do + ActiveScheduler.config.guard_with = ->(*) { true } + end + + after do + ActiveScheduler.config.guard_with = guard_with + end + + it "wraps the job" do + stub_jobs("SimpleJob", base_class: Class.new) + expect(wrapped['simple_job']).to eq( + "class" => "ActiveScheduler::ResqueWrapper", + "queue" => "simple", + "description" => "It's a simple job.", + "every" => "30s", + "rails_env" => "test", + "args" => [{ + "job_class" => "SimpleJob", + "queue_name" => "simple", + "arguments" => ['foo-arg-1', 'foo-arg-2'], + }] + ) + end end end @@ -125,14 +157,40 @@ class CustomWrapper < ActiveScheduler::ResqueWrapper context "when the queue is blank" do let(:schedule) { YAML.load_file 'spec/fixtures/no_queue.yaml' } - it "uses the job's queue" do - simple_job = Class.new(ActiveJob::Base) do - queue_as :myscheduledjobqueue + context "with default configuration" do + it "uses the job's queue" do + simple_job = Class.new(ActiveJob::Base) do + queue_as :myscheduledjobqueue + end + + stub_jobs("SimpleJob", base_class: simple_job) + + expect(wrapped['no_queue_job']['queue']).to eq 'myscheduledjobqueue' end + end - stub_const("SimpleJob", simple_job) + context "with a custom queue_name_resolver configuration" do + let!(:queue_name_resolver) do + ActiveScheduler.config.queue_name_resolver + end - expect(wrapped['no_queue_job']['queue']).to eq 'myscheduledjobqueue' + before do + ActiveScheduler.config.queue_name_resolver = ->(*) { 'test' } + end + + after do + ActiveScheduler.config.queue_name_resolver = queue_name_resolver + end + + it "uses the queue name resolver" do + simple_job = Class.new(ActiveJob::Base) do + queue_as :myscheduledjobqueue + end + + stub_jobs("SimpleJob", base_class: simple_job) + + expect(wrapped['no_queue_job']['queue']).to eq 'test' + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3902c78..e31eaae 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,9 +6,9 @@ end module Helpers - def stub_jobs(*names) + def stub_jobs(*names, base_class: ActiveJob::Base) names.each do |name| - stub_const(name, Class.new(ActiveJob::Base)) + stub_const(name, Class.new(base_class)) end end end