diff --git a/app/jobs/base.rb b/app/jobs/base.rb index 379ed72b985..0693fb9bbdc 100644 --- a/app/jobs/base.rb +++ b/app/jobs/base.rb @@ -293,32 +293,45 @@ module Jobs opts[:current_site_id] ||= RailsMultisite::ConnectionManagement.current_db end - # If we are able to queue a job, do it + delay = opts.delete(:delay_for) + queue = opts.delete(:queue) + + # Only string keys are allowed in JSON. We call `.with_indifferent_access` + # in Jobs::Base#perform, so this is invisible to developers + opts = opts.stringify_keys + + # Simulate the args being dumped/parsed through JSON + parsed_opts = JSON.parse(JSON.dump(opts)) + if opts != parsed_opts + Discourse.deprecate(<<~MSG.squish, since: "v2.9", drop_from: "3.0") + #{klass.name} was enqueued with argument values which do not cleanly serialize to/from JSON. + This means that the job will be run with slightly different values than the ones supplied to `enqueue`. + Argument values should be strings, booleans, numbers, or nil (or arrays/hashes of those value types). + MSG + end + opts = parsed_opts if ::Jobs.run_later? hash = { - 'class' => klass + 'class' => klass, + 'args' => [opts] } - if delay = opts.delete(:delay_for) + if delay if delay.to_f > 0 hash['at'] = Time.now.to_f + delay.to_f end end - if queue = opts.delete(:queue) + if queue hash['queue'] = queue end - hash['args'] = [opts.deep_stringify_keys] - DB.after_commit { klass.client_push(hash) } else # Otherwise execute the job right away - opts.delete(:delay_for) - opts.delete(:queue) + opts["sync_exec"] = true - opts[:sync_exec] = true if Rails.env == "development" Scheduler::Defer.later("job") do klass.new.perform(opts) diff --git a/config/initializers/100-sidekiq.rb b/config/initializers/100-sidekiq.rb index 99d9da4cfd2..4f7a77b69a5 100644 --- a/config/initializers/100-sidekiq.rb +++ b/config/initializers/100-sidekiq.rb @@ -122,3 +122,5 @@ end Sidekiq.error_handlers.clear Sidekiq.error_handlers << SidekiqLogsterReporter.new + +Sidekiq.strict_args! diff --git a/spec/jobs/jobs_spec.rb b/spec/jobs/jobs_spec.rb index 113f8e57889..ad130c2530e 100644 --- a/spec/jobs/jobs_spec.rb +++ b/spec/jobs/jobs_spec.rb @@ -108,7 +108,7 @@ describe Jobs do end it "executes the job right away" do - Jobs::ProcessPost.any_instance.expects(:perform).with(post_id: 1, sync_exec: true, current_site_id: "default") + Jobs::ProcessPost.any_instance.expects(:perform).with("post_id" => 1, "sync_exec" => true, "current_site_id" => "default") Jobs.enqueue(:process_post, post_id: 1) end