1
0
Fork 0
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:
Mike Perham 2012-08-04 12:11:46 -07:00
parent c1da2f0034
commit 8357fa3e4b
3 changed files with 23 additions and 1 deletions

View file

@ -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
-----------

View file

@ -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

View file

@ -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