-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Infer interruption handler from a job's queue adapter
...and allow Iteration to be used with multiple job backends simultaneously Removed test_mark_job_worker_as_interrupted since it was testing stubs Co-authored-by: Justin Morris <[email protected]>
- Loading branch information
1 parent
a428f69
commit e348b67
Showing
12 changed files
with
108 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# frozen_string_literal: true | ||
|
||
module JobIteration | ||
# @api private | ||
module Integrations | ||
LoadError = Class.new(StandardError) | ||
|
||
extend self | ||
|
||
attr_accessor :registered_integrations | ||
|
||
self.registered_integrations = {} | ||
|
||
autoload :Sidekiq, "job-iteration/integrations/sidekiq" | ||
autoload :Resque, "job-iteration/integrations/resque" | ||
|
||
# @api public | ||
def register(name, callable) | ||
raise ArgumentError, "Interruption adapter must respond to #call" unless callable.respond_to?(:call) | ||
|
||
registered_integrations[name] = callable | ||
end | ||
|
||
def load(name) | ||
if (callable = registered_integrations[name]) | ||
callable | ||
else | ||
begin | ||
klass = "#{self}::#{name.camelize}".constantize | ||
register(name, klass) | ||
rescue NameError | ||
raise LoadError, "Could not find integration for '#{name}'" | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,46 @@ | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
require "open3" | ||
|
||
class IntegrationsTest < ActiveSupport::TestCase | ||
test "will prevent loading two integrations" do | ||
with_env("ITERATION_DISABLE_AUTOCONFIGURE", nil) do | ||
rubby = <<~RUBBY | ||
require 'bundler/setup' | ||
require 'job-iteration' | ||
RUBBY | ||
_stdout, stderr, status = run_ruby(rubby) | ||
|
||
assert_equal false, status.success? | ||
assert_match(/resque integration has already been loaded, but sidekiq is also available/, stderr) | ||
|
||
class IntegrationsTest < IterationUnitTest | ||
class IterationJob < ActiveJob::Base | ||
include JobIteration::Iteration | ||
|
||
def build_enumerator(cursor:) | ||
enumerator_builder.build_once_enumerator(cursor: cursor) | ||
end | ||
end | ||
|
||
test "successfully loads one (resque) integration" do | ||
with_env("ITERATION_DISABLE_AUTOCONFIGURE", nil) do | ||
rubby = <<~RUBBY | ||
require 'bundler/setup' | ||
# Remove sidekiq, only resque will be left | ||
$LOAD_PATH.delete_if { |p| p =~ /sidekiq/ } | ||
require 'job-iteration' | ||
RUBBY | ||
_stdout, _stderr, status = run_ruby(rubby) | ||
|
||
assert_equal true, status.success? | ||
def each_iteration(*) | ||
end | ||
end | ||
|
||
private | ||
class ResqueJob < IterationJob | ||
self.queue_adapter = :resque | ||
end | ||
|
||
def run_ruby(body) | ||
stdout, stderr, status = nil | ||
Tempfile.open do |f| | ||
f.write(body) | ||
f.close | ||
class SidekiqJob < IterationJob | ||
self.queue_adapter = :sidekiq | ||
end | ||
|
||
command = "ruby #{f.path}" | ||
stdout, stderr, status = Open3.capture3(command) | ||
test "loads multiple integrations" do | ||
resque_job = ResqueJob.new.serialize | ||
ActiveJob::Base.execute(resque_job) | ||
|
||
sidekiq_job = SidekiqJob.new.serialize | ||
ActiveJob::Base.execute(sidekiq_job) | ||
end | ||
|
||
test ".register raises when the callable object does not implement #call" do | ||
error = assert_raises(ArgumentError) do | ||
JobIteration::Integrations.register("foo", "bar") | ||
end | ||
[stdout, stderr, status] | ||
assert_equal("Interruption adapter must respond to #call", error.message) | ||
end | ||
|
||
def with_env(variable, value) | ||
original = ENV[variable] | ||
ENV[variable] = value | ||
yield | ||
ensure | ||
ENV[variable] = original | ||
test "raises for unknown Active Job queue adapter names" do | ||
error = assert_raises(JobIteration::Integrations::LoadError) do | ||
JobIteration::Integrations.load("unknown") | ||
end | ||
assert_equal("Could not find integration for 'unknown'", error.message) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters