diff --git a/config/initializers/100-sidekiq.rb b/config/initializers/100-sidekiq.rb index 6932de68965..11b30f50ae3 100644 --- a/config/initializers/100-sidekiq.rb +++ b/config/initializers/100-sidekiq.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "sidekiq/pausable" +require "sidekiq/discourse_event" require "sidekiq_logster_reporter" require "sidekiq_long_running_job_logger" require "mini_scheduler_long_running_job_logger" @@ -10,7 +11,10 @@ Sidekiq.configure_client { |config| config.redis = Discourse.sidekiq_redis_confi Sidekiq.configure_server do |config| config.redis = Discourse.sidekiq_redis_config - config.server_middleware { |chain| chain.add Sidekiq::Pausable } + config.server_middleware do |chain| + chain.add Sidekiq::Pausable + chain.add Sidekiq::DiscourseEvent + end if stuck_sidekiq_job_minutes = GlobalSetting.sidekiq_report_long_running_jobs_minutes config.on(:startup) { SidekiqLongRunningJobLogger.new(stuck_sidekiq_job_minutes:).start } diff --git a/lib/sidekiq/discourse_event.rb b/lib/sidekiq/discourse_event.rb new file mode 100644 index 00000000000..998bd0dfd69 --- /dev/null +++ b/lib/sidekiq/discourse_event.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class Sidekiq::DiscourseEvent + def call(worker, msg, queue) + start_time = clock_gettime + result = yield + trigger_discourse_event(event_name: :sidekiq_job_ran, worker:, msg:, queue:, start_time:) + result + rescue => error + trigger_discourse_event(event_name: :sidekiq_job_error, worker:, msg:, queue:, start_time:) + raise error + end + + private + + def trigger_discourse_event(event_name:, worker:, msg:, queue:, start_time:) + duration = clock_gettime - start_time + DiscourseEvent.trigger(event_name, worker, msg, queue, duration) + end + + def clock_gettime + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end +end diff --git a/lib/sidekiq/pausable.rb b/lib/sidekiq/pausable.rb index 6f1a2e901f6..dae0220ecdd 100644 --- a/lib/sidekiq/pausable.rb +++ b/lib/sidekiq/pausable.rb @@ -128,11 +128,7 @@ class Sidekiq::Pausable if sidekiq_paused?(msg) worker.class.perform_in(@delay, *msg["args"]) else - start = Process.clock_gettime(Process::CLOCK_MONOTONIC) - result = yield - duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start - DiscourseEvent.trigger(:sidekiq_job_ran, worker, msg, queue, duration) - result + yield end end diff --git a/spec/lib/sidekiq/discourse_event_spec.rb b/spec/lib/sidekiq/discourse_event_spec.rb new file mode 100644 index 00000000000..7febd368202 --- /dev/null +++ b/spec/lib/sidekiq/discourse_event_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +RSpec.describe Sidekiq::DiscourseEvent do + describe "#call" do + it "should trigger the `sidekiq_job_ran` discourse event when successfully executing the block" do + called = false + + events = + DiscourseEvent.track_events(:sidekiq_job_ran) do + described_class + .new + .call("SomeClass", { some_key: "some_value" }, "some_queue_name") { called = true } + end + + expect(called).to eq(true) + expect(events.length).to eq(1) + + event = events.first + + expect(event[:event_name]).to eq(:sidekiq_job_ran) + expect(event[:params][0]).to eq("SomeClass") + expect(event[:params][1]).to eq({ some_key: "some_value" }) + expect(event[:params][2]).to eq("some_queue_name") + expect(event[:params][3]).to be_a(Float) + end + + it "should trigger `sidekiq_job_error` discourse event when an error occurs while executing the block" do + called = false + + events = + DiscourseEvent.track_events(:sidekiq_job_error) do + expect do + described_class + .new + .call("SomeClass", { some_key: "some_value" }, "some_queue_name") do + called = true + raise StandardError, "Boom!" + end + end.to raise_error(StandardError, "Boom!") + end + + expect(called).to eq(true) + expect(events.length).to eq(1) + + event = events.first + + expect(event[:event_name]).to eq(:sidekiq_job_error) + expect(event[:params][0]).to eq("SomeClass") + expect(event[:params][1]).to eq({ some_key: "some_value" }) + expect(event[:params][2]).to eq("some_queue_name") + expect(event[:params][3]).to be_a(Float) + end + end +end