diff --git a/app/jobs/base.rb b/app/jobs/base.rb index 0bd5b6fe352..a7d23994a0f 100644 --- a/app/jobs/base.rb +++ b/app/jobs/base.rb @@ -197,14 +197,28 @@ module Jobs # If we are able to queue a job, do it if SiteSetting.queue_jobs? - if opts[:delay_for].present? - klass.perform_in(opts.delete(:delay_for), opts) - else - Sidekiq::Client.enqueue(klass, opts) + hash = { + 'class' => klass, + 'args' => [opts] + } + + if delay = opts.delete(:delay_for) + if delay.to_f > 0 + hash['at'] = Time.now.to_f + delay.to_f + end end + + if queue = opts.delete(:queue) + hash['queue'] = queue + end + + klass.client_push(hash) + else # Otherwise execute the job right away opts.delete(:delay_for) + opts.delete(:queue) + opts[:sync_exec] = true if Rails.env == "development" Scheduler::Defer.later("job") do diff --git a/app/jobs/scheduled/periodical_updates.rb b/app/jobs/scheduled/periodical_updates.rb index 2ab95178081..5701e6d6fd3 100644 --- a/app/jobs/scheduled/periodical_updates.rb +++ b/app/jobs/scheduled/periodical_updates.rb @@ -15,7 +15,7 @@ module Jobs (@call_count % 24) == 1 end - def execute(args) + def execute(args = nil) # Feature topics in categories CategoryFeaturedTopic.feature_topics(batched: true) @@ -29,7 +29,7 @@ module Jobs # Forces rebake of old posts where needed, as long as no system avatars need updating if !SiteSetting.automatically_download_gravatars || !UserAvatar.where("last_gravatar_download_attempt IS NULL").limit(1).first - problems = Post.rebake_old(SiteSetting.rebake_old_posts_count) + problems = Post.rebake_old(SiteSetting.rebake_old_posts_count, priority: :low) problems.each do |hash| post_id = hash[:post].id Discourse.handle_job_exception(hash[:ex], error_context(args, "Rebaking post id #{post_id}", post_id: post_id)) diff --git a/app/models/post.rb b/app/models/post.rb index ff6c32890b4..19d093d967b 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -515,7 +515,7 @@ class Post < ActiveRecord::Base PostRevisor.new(self).revise!(updated_by, changes, opts) end - def self.rebake_old(limit) + def self.rebake_old(limit, priority: :normal) limiter = RateLimiter.new( nil, @@ -534,7 +534,7 @@ class Post < ActiveRecord::Base break if !limiter.can_perform? post = Post.find(id) - post.rebake! + post.rebake!(priority: priority) begin limiter.performed! @@ -560,15 +560,13 @@ class Post < ActiveRecord::Base problems end - def rebake!(opts = nil) - opts ||= {} - - new_cooked = cook(raw, topic_id: topic_id, invalidate_oneboxes: opts.fetch(:invalidate_oneboxes, false)) + def rebake!(invalidate_broken_images: false, invalidate_oneboxes: false, priority: nil) + new_cooked = cook(raw, topic_id: topic_id, invalidate_oneboxes: invalidate_oneboxes) old_cooked = cooked update_columns(cooked: new_cooked, baked_at: Time.new, baked_version: BAKED_VERSION) - if opts.fetch(:invalidate_broken_images, false) + if invalidate_broken_images custom_fields.delete(BROKEN_IMAGES) save_custom_fields end @@ -578,7 +576,7 @@ class Post < ActiveRecord::Base QuotedPost.extract_from(self) # make sure we trigger the post process - trigger_post_process(bypass_bump: true) + trigger_post_process(bypass_bump: true, priority: priority) publish_change_to_clients!(:rebaked) @@ -692,7 +690,7 @@ class Post < ActiveRecord::Base end # Enqueue post processing for this post - def trigger_post_process(bypass_bump: false) + def trigger_post_process(bypass_bump: false, priority: :normal) args = { post_id: id, bypass_bump: bypass_bump, @@ -700,6 +698,11 @@ class Post < ActiveRecord::Base args[:image_sizes] = image_sizes if image_sizes.present? args[:invalidate_oneboxes] = true if invalidate_oneboxes.present? args[:cooking_options] = self.cooking_options + + if priority == :low + args[:queue] = 'low' + end + Jobs.enqueue(:process_post, args) DiscourseEvent.trigger(:after_trigger_post_process, self) end diff --git a/spec/jobs/periodical_updates_spec.rb b/spec/jobs/periodical_updates_spec.rb index b2ba6c60def..8b0e88bfc68 100644 --- a/spec/jobs/periodical_updates_spec.rb +++ b/spec/jobs/periodical_updates_spec.rb @@ -13,13 +13,24 @@ describe Jobs::PeriodicalUpdates do SiteSetting.automatically_download_gravatars = false post = create_post post.update_columns(baked_at: Time.new(2000, 1, 1), baked_version: -1) - described_class.new.execute({}) + + Sidekiq::Testing.fake! do + Jobs::ProcessPost.jobs.clear + + Jobs::PeriodicalUpdates.new.execute + + jobs = Jobs::ProcessPost.jobs + expect(jobs.length).to eq(1) + + expect(jobs[0]["queue"]).to eq("low") + end post.reload expect(post.baked_at).to be > 1.day.ago - baked = post.baked_at - described_class.new.execute({}) + + # does not rebake + Jobs::PeriodicalUpdates.new.execute post.reload expect(post.baked_at).to eq(baked) end