Skip to content

Commit 26689a5

Browse files
committed
fix: sidekiq options must have string keys
1 parent dac8399 commit 26689a5

File tree

3 files changed

+48
-36
lines changed

3 files changed

+48
-36
lines changed

Gemfile

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ source 'https://rubygems.org'
44

55
gemspec
66

7-
gem 'bundler'
8-
gem 'rake'
9-
gem 'rspec'
7+
gem "bundler"
8+
gem "rake"
9+
gem "sidekiq", "~> 7.3.6"
10+
gem "activesupport", "~> 7", require: true
11+
12+
group :test do
13+
gem "rspec", "~> 3.13"
14+
end

lib/interactor/sidekiq.rb

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
require 'interactor'
44
require 'sidekiq'
5+
require 'active_support/core_ext/hash'
56

67
module Interactor
78
# Internal: Install Interactor's behavior in the given class.
@@ -36,36 +37,36 @@ class Worker
3637
end
3738
end
3839

39-
def perform(context)
40-
interactor_class(context).sync_call(context.reject { |c| ['interactor_class'].include? c.to_s })
40+
def perform(interactor_context)
41+
interactor_class(interactor_context).sync_call(interactor_context.reject { |c| ['interactor_class'].include? c.to_s })
4142
rescue Exception => e
42-
if interactor_class(context).respond_to?(:handle_sidekiq_exception)
43-
interactor_class(context).handle_sidekiq_exception(e)
43+
if interactor_class(interactor_context).respond_to?(:handle_sidekiq_exception)
44+
interactor_class(interactor_context).handle_sidekiq_exception(e)
4445
else
4546
raise e
4647
end
4748
end
4849

4950
private
5051

51-
def interactor_class(context)
52-
Module.const_get context[:interactor_class]
52+
def interactor_class(interactor_context)
53+
Module.const_get interactor_context[:interactor_class]
5354
end
5455
end
5556

56-
def sync_call(context = {})
57-
new(context).tap(&:run!).context
57+
def sync_call(interactor_context = {})
58+
new(interactor_context).tap(&:run!).context
5859
end
5960

60-
def async_call(context = {})
61-
options = handle_sidekiq_options(context)
62-
schedule_options = delay_sidekiq_schedule_options(context)
61+
def async_call(interactor_context = {})
62+
options = handle_sidekiq_options(interactor_context)
63+
schedule_options = delay_sidekiq_schedule_options(interactor_context)
6364

64-
worker_class.set(options).perform_in(schedule_options.fetch(:delay, 0), handle_context_for_sidekiq(context))
65-
new(context.to_h).context
65+
worker_class.set(options).perform_in(schedule_options.fetch(:delay, 0), handle_context_for_sidekiq(interactor_context))
66+
new(interactor_context.to_h).context
6667
rescue Exception => e
6768
begin
68-
new(context.to_h).context.fail!(error: e.message)
69+
new(interactor_context.to_h).context.fail!(error: e.message)
6970
rescue Failure => e
7071
e.context
7172
end
@@ -81,30 +82,30 @@ def worker_class
8182
raise "#{klass} is not a valid Sidekiq worker class. It must be a subclass of ::Interactor::SidekiqWorker::Worker."
8283
end
8384

84-
def handle_context_for_sidekiq(context)
85-
context.to_h.merge(interactor_class: to_s)
85+
def handle_context_for_sidekiq(interactor_context)
86+
interactor_context.to_h.merge(interactor_class: to_s).except(:sidekiq_options).except(:sidekiq_schedule_options).stringify_keys
8687
end
8788

88-
def handle_sidekiq_options(context)
89-
if context[:sidekiq_options].nil?
89+
def handle_sidekiq_options(interactor_context)
90+
if interactor_context[:sidekiq_options].nil?
9091
respond_to?(:sidekiq_options) ? sidekiq_options : { queue: :default }
9192
else
92-
context[:sidekiq_options]
93+
interactor_context[:sidekiq_options]
9394
end
9495
end
9596

96-
def delay_sidekiq_schedule_options(context)
97-
options = handle_sidekiq_schedule_options(context)
97+
def delay_sidekiq_schedule_options(interactor_context)
98+
options = handle_sidekiq_schedule_options(interactor_context)
9899
return {} unless options.key?(:perform_in) || options.key?(:perform_at)
99100

100101
{ delay: options[:perform_in] || options[:perform_at] }
101102
end
102103

103-
def handle_sidekiq_schedule_options(context)
104-
if context[:sidekiq_schedule_options].nil?
104+
def handle_sidekiq_schedule_options(interactor_context)
105+
if interactor_context[:sidekiq_schedule_options].nil?
105106
respond_to?(:sidekiq_schedule_options) ? sidekiq_schedule_options : { delay: 0 }
106107
else
107-
context[:sidekiq_schedule_options]
108+
interactor_context[:sidekiq_schedule_options]
108109
end
109110
end
110111
end
@@ -133,18 +134,18 @@ def self.included(base)
133134
end
134135

135136
module ClassMethods
136-
def call(context = {})
137-
default_async_call(context)
137+
def call(interactor_context = {})
138+
default_async_call(interactor_context)
138139
end
139140

140-
def call!(context = {})
141-
default_async_call(context)
141+
def call!(interactor_context = {})
142+
default_async_call(interactor_context)
142143
end
143144

144145
private
145146

146-
def default_async_call(context)
147-
async_call(context)
147+
def default_async_call(interactor_context)
148+
async_call(interactor_context)
148149
end
149150
end
150151
end

spec/interactor/sidekiq_worker_spec.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,11 @@ class OrganizerWithAsyncAction
8989

9090
it { expect(jobs_by_queue['queue']).to eq elements[:sidekiq_options][:queue] }
9191

92-
it { expect(jobs_by_queue['args']).to eq [context.merge(interactor_class: elements[:interactor_class]).to_json] }
92+
it "is queued with the correct arguments" do
93+
expect(jobs_by_queue['args']).to eq(
94+
[context.merge(interactor_class: elements[:interactor_class]).except(:sidekiq_options).except(:sidekiq_schedule_options).stringify_keys]
95+
)
96+
end
9397
end
9498

9599
shared_examples_for 'there is no sidekiq worker' do
@@ -140,8 +144,10 @@ class OrganizerWithAsyncAction
140144
{ key: 'value', sidekiq_options: { queue: 'low_priority' }, sidekiq_schedule_options: { perform_in: 5 } }
141145
end
142146

143-
it_behaves_like 'sidekiq worker', interactor_class: interactor_class, sidekiq_options: { queue: 'low_priority' },
144-
sidekiq_schedule_options: { perform_in: 5 }
147+
it_behaves_like 'sidekiq worker',
148+
interactor_class: interactor_class,
149+
sidekiq_options: { queue: 'low_priority' },
150+
sidekiq_schedule_options: { perform_in: 5 }
145151

146152
it_behaves_like 'interactor success'
147153
end

0 commit comments

Comments
 (0)