mirror of
https://github.com/mperham/sidekiq.git
synced 2022-11-09 13:52:34 -05:00
Clone arguments before calling workers to avoid mutation [#265]
This commit is contained in:
parent
c1da2f0034
commit
8357fa3e4b
3 changed files with 23 additions and 1 deletions
|
@ -3,6 +3,7 @@ HEAD
|
|||
|
||||
- Handle networking errors causing the scheduler thread to die [#309]
|
||||
- Rework exception handling to log all Processor and actor death (#325, subelsky)
|
||||
- Clone arguments when calling worker so modifications are discarded. (hakanensari)
|
||||
|
||||
2.1.0
|
||||
-----------
|
||||
|
|
|
@ -37,7 +37,7 @@ module Sidekiq
|
|||
|
||||
stats(worker, msg, queue) do
|
||||
Sidekiq.server_middleware.invoke(worker, msg, queue) do
|
||||
worker.perform(*msg['args'])
|
||||
worker.perform(*cloned(msg['args']))
|
||||
end
|
||||
end
|
||||
@boss.processor_done!(current_actor)
|
||||
|
@ -57,6 +57,9 @@ module Sidekiq
|
|||
|
||||
private
|
||||
|
||||
# Singleton classes are not clonable.
|
||||
SINGLETON_CLASSES = [ NilClass, TrueClass, FalseClass, Numeric, Symbol ].freeze
|
||||
|
||||
def stats(worker, msg, queue)
|
||||
redis do |conn|
|
||||
conn.multi do
|
||||
|
@ -88,7 +91,15 @@ module Sidekiq
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Clone the arguments passed to the worker so that if
|
||||
# the message fails, what is pushed back onto Redis hasn't
|
||||
# been mutated by the worker.
|
||||
def cloned(ary)
|
||||
ary.map do |val|
|
||||
SINGLETON_CLASSES.include?(val.class) ? val : val.clone
|
||||
end
|
||||
end
|
||||
|
||||
def hostname
|
||||
|
|
|
@ -18,6 +18,7 @@ class TestProcessor < MiniTest::Unit::TestCase
|
|||
include Sidekiq::Worker
|
||||
def perform(args)
|
||||
raise TEST_EXCEPTION if args == 'boom'
|
||||
args.pop if args.is_a? Array
|
||||
$invokes += 1
|
||||
end
|
||||
end
|
||||
|
@ -53,5 +54,14 @@ class TestProcessor < MiniTest::Unit::TestCase
|
|||
|
||||
assert re_raise, "does not re-raise exceptions after handling"
|
||||
end
|
||||
|
||||
it 'does not modify original arguments' do
|
||||
msg = { 'class' => MockWorker.to_s, 'args' => [['myarg']] }
|
||||
msgstr = Sidekiq.dump_json(msg)
|
||||
processor = ::Sidekiq::Processor.new(@boss)
|
||||
@boss.expect(:processor_done!, nil, [processor])
|
||||
processor.process(msgstr, 'default')
|
||||
assert_equal [['myarg']], msg['args']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue