DEV: Prevent defer stats exception when thread aborted (#19863)

When the thread is aborted, an exception is raised before the `start` of a job is set, and therefore raises an exception in the `ensure` block. This commit checks that `start` exists, and also adds `abort_on_exception=true` so that this issue would have caused test failures.
This commit is contained in:
David Taylor 2023-01-15 22:08:44 +00:00 committed by GitHub
parent f72875c729
commit 29f7ec7090
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 8 deletions

View File

@ -191,6 +191,18 @@ module Discourse
reset_job_exception_stats!
if Rails.env.test?
def self.catch_job_exceptions!
raise "tests only" if !Rails.env.test?
@catch_job_exceptions = true
end
def self.reset_catch_job_exceptions!
raise "tests only" if !Rails.env.test?
remove_instance_variable(:@catch_job_exceptions)
end
end
# Log an exception.
#
# If your code is in a scheduled job, it is recommended to use the
@ -220,7 +232,7 @@ module Discourse
{ current_db: cm.current_db, current_hostname: cm.current_hostname }.merge(context),
)
raise ex if Rails.env.test?
raise ex if Rails.env.test? && !@catch_job_exceptions
end
# Expected less matches than what we got in a find

View File

@ -79,7 +79,11 @@ module Scheduler
def start_thread
@mutex.synchronize do
@reactor = MessageBus::TimerThread.new if !@reactor
@thread = Thread.new { do_work while true } if !@thread&.alive?
@thread =
Thread.new do
@thread.abort_on_exception = true if Rails.env.test?
do_work while true
end if !@thread&.alive?
end
end
@ -110,11 +114,13 @@ module Scheduler
Discourse.handle_job_exception(ex, message: "Processing deferred code queue")
ensure
ActiveRecord::Base.connection_handler.clear_active_connections!
@stats_mutex.synchronize do
stats = @stats[desc]
if stats
stats[:finished] += 1
stats[:duration] += Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
if start
@stats_mutex.synchronize do
stats = @stats[desc]
if stats
stats[:finished] += 1
stats[:duration] += Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
end
end
end
end

View File

@ -12,11 +12,15 @@ RSpec.describe Scheduler::Defer do
end
before do
Discourse.catch_job_exceptions!
@defer = DeferInstance.new
@defer.async = true
end
after { @defer.stop! }
after do
@defer.stop!
Discourse.reset_catch_job_exceptions!
end
it "supports basic instrumentation" do
@defer.later("first") {}