mirror of
https://github.com/discourse/discourse.git
synced 2025-05-25 19:01:27 +08:00
DEV: Upgrade Sidekiq to v7.3.9
This commit is contained in:

committed by
Loïc Guitaut

parent
19acb61834
commit
3dbbb940de
15
Gemfile.lock
15
Gemfile.lock
@ -428,6 +428,8 @@ GEM
|
|||||||
psych (>= 4.0.0)
|
psych (>= 4.0.0)
|
||||||
redcarpet (3.6.1)
|
redcarpet (3.6.1)
|
||||||
redis (4.8.1)
|
redis (4.8.1)
|
||||||
|
redis-client (0.23.2)
|
||||||
|
connection_pool
|
||||||
redis-namespace (1.11.0)
|
redis-namespace (1.11.0)
|
||||||
redis (>= 4)
|
redis (>= 4)
|
||||||
regexp_parser (2.10.0)
|
regexp_parser (2.10.0)
|
||||||
@ -558,10 +560,12 @@ GEM
|
|||||||
websocket (~> 1.0)
|
websocket (~> 1.0)
|
||||||
shoulda-matchers (6.4.0)
|
shoulda-matchers (6.4.0)
|
||||||
activesupport (>= 5.2.0)
|
activesupport (>= 5.2.0)
|
||||||
sidekiq (6.5.12)
|
sidekiq (7.3.9)
|
||||||
connection_pool (>= 2.2.5, < 3)
|
base64
|
||||||
rack (~> 2.0)
|
connection_pool (>= 2.3.0)
|
||||||
redis (>= 4.5.0, < 5)
|
logger
|
||||||
|
rack (>= 2.2.4)
|
||||||
|
redis-client (>= 0.22.2)
|
||||||
simplecov (0.22.0)
|
simplecov (0.22.0)
|
||||||
docile (~> 1.1)
|
docile (~> 1.1)
|
||||||
simplecov-html (~> 0.11)
|
simplecov-html (~> 0.11)
|
||||||
@ -999,6 +1003,7 @@ CHECKSUMS
|
|||||||
rdoc (6.12.0) sha256=7d6f706e070bffa5d18a448f24076cbfb34923a99c1eab842aa18e6ca69f56e0
|
rdoc (6.12.0) sha256=7d6f706e070bffa5d18a448f24076cbfb34923a99c1eab842aa18e6ca69f56e0
|
||||||
redcarpet (3.6.1) sha256=d444910e6aa55480c6bcdc0cdb057626e8a32c054c29e793fa642ba2f155f445
|
redcarpet (3.6.1) sha256=d444910e6aa55480c6bcdc0cdb057626e8a32c054c29e793fa642ba2f155f445
|
||||||
redis (4.8.1) sha256=387ee086694fffc9632aaeb1efe4a7b1627ca783bf373320346a8a20cd93333a
|
redis (4.8.1) sha256=387ee086694fffc9632aaeb1efe4a7b1627ca783bf373320346a8a20cd93333a
|
||||||
|
redis-client (0.23.2) sha256=e33bab6682c8155cfef95e6dd296936bb9c2981a89fb578ace27a076fa2836fa
|
||||||
redis-namespace (1.11.0) sha256=e91a1aa2b2d888b6dea1d4ab8d39e1ae6fac3426161feb9d91dd5cca598a2239
|
redis-namespace (1.11.0) sha256=e91a1aa2b2d888b6dea1d4ab8d39e1ae6fac3426161feb9d91dd5cca598a2239
|
||||||
regexp_parser (2.10.0) sha256=cb6f0ddde88772cd64bff1dbbf68df66d376043fe2e66a9ef77fcb1b0c548c61
|
regexp_parser (2.10.0) sha256=cb6f0ddde88772cd64bff1dbbf68df66d376043fe2e66a9ef77fcb1b0c548c61
|
||||||
reline (0.6.0) sha256=57620375dcbe56ec09bac7192bfb7460c716bbf0054dc94345ecaa5438e539d2
|
reline (0.6.0) sha256=57620375dcbe56ec09bac7192bfb7460c716bbf0054dc94345ecaa5438e539d2
|
||||||
@ -1048,7 +1053,7 @@ CHECKSUMS
|
|||||||
selenium-devtools (0.133.0) sha256=aba5a5225ac38d235bbc6ebb4e0b8209e973ac7af4226e4304a1417573f73f64
|
selenium-devtools (0.133.0) sha256=aba5a5225ac38d235bbc6ebb4e0b8209e973ac7af4226e4304a1417573f73f64
|
||||||
selenium-webdriver (4.29.1) sha256=0a7fe53cc4d2c515adbb89e115c6e786c64e9b98f85939d21071c6e32883a146
|
selenium-webdriver (4.29.1) sha256=0a7fe53cc4d2c515adbb89e115c6e786c64e9b98f85939d21071c6e32883a146
|
||||||
shoulda-matchers (6.4.0) sha256=9055bb7f4bb342125fb860809798855c630e05ef5e75837b3168b8e6ee1608b0
|
shoulda-matchers (6.4.0) sha256=9055bb7f4bb342125fb860809798855c630e05ef5e75837b3168b8e6ee1608b0
|
||||||
sidekiq (6.5.12) sha256=b4f93b2204c42220d0b526a7b8e0c49b5f9da82c1ce1a05d2baf1e8f744c197f
|
sidekiq (7.3.9) sha256=1108712e1def89002b28e3545d5ae15d4a57ffd4d2c25d97bb1360988826b5a7
|
||||||
simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5
|
simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5
|
||||||
simplecov-html (0.13.1) sha256=5dab0b7ee612e60e9887ad57693832fdf4695b4c0c859eaea5f95c18791ef10b
|
simplecov-html (0.13.1) sha256=5dab0b7ee612e60e9887ad57693832fdf4695b4c0c859eaea5f95c18791ef10b
|
||||||
simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428
|
simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428
|
||||||
|
@ -475,7 +475,7 @@ module Jobs
|
|||||||
Sidekiq::ScheduledSet.new.select do |scheduled_job|
|
Sidekiq::ScheduledSet.new.select do |scheduled_job|
|
||||||
if scheduled_job.klass.to_s == job_class
|
if scheduled_job.klass.to_s == job_class
|
||||||
matched = true
|
matched = true
|
||||||
job_params = scheduled_job.item["args"][0].with_indifferent_access
|
job_params = scheduled_job.args[0].with_indifferent_access
|
||||||
opts.each do |key, value|
|
opts.each do |key, value|
|
||||||
if job_params[key] != value
|
if job_params[key] != value
|
||||||
matched = false
|
matched = false
|
||||||
|
@ -66,16 +66,17 @@ else
|
|||||||
#
|
#
|
||||||
# Instead, this patch adds a dedicated logger instance and patches
|
# Instead, this patch adds a dedicated logger instance and patches
|
||||||
# the #add method to forward messages to Rails.logger.
|
# the #add method to forward messages to Rails.logger.
|
||||||
Sidekiq.logger = Logger.new(nil)
|
Sidekiq.default_configuration.logger = Logger.new(nil)
|
||||||
Sidekiq
|
Sidekiq
|
||||||
|
.default_configuration
|
||||||
.logger
|
.logger
|
||||||
.define_singleton_method(:add) do |severity, message = nil, progname = nil, &blk|
|
.define_singleton_method(:add) do |severity, message = nil, progname = nil, &blk|
|
||||||
Rails.logger.add(severity, message, progname, &blk)
|
Rails.logger.add(severity, message, progname, &blk)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Sidekiq.error_handlers.clear
|
Sidekiq.default_configuration.error_handlers.clear
|
||||||
Sidekiq.error_handlers << SidekiqLogsterReporter.new
|
Sidekiq.default_configuration.error_handlers << SidekiqLogsterReporter.new
|
||||||
|
|
||||||
Sidekiq.strict_args!
|
Sidekiq.strict_args!
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Delete this migration instead of promoting it (along with the
|
# TODO: Remove this after the Discourse 3.5 release
|
||||||
# `SidekiqMigration` class)
|
|
||||||
class MigrateSidekiqJobs < ActiveRecord::Migration[7.2]
|
class MigrateSidekiqJobs < ActiveRecord::Migration[7.2]
|
||||||
def up
|
def up
|
||||||
SidekiqMigration.call
|
SidekiqMigration.call
|
||||||
|
@ -115,7 +115,7 @@ module BackupRestore
|
|||||||
|
|
||||||
def sidekiq_has_running_jobs?
|
def sidekiq_has_running_jobs?
|
||||||
Sidekiq::Workers.new.each do |_, _, work|
|
Sidekiq::Workers.new.each do |_, _, work|
|
||||||
args = work&.dig("payload", "args")&.first
|
args = work.job.args&.first
|
||||||
current_site_id = args["current_site_id"] if args.present?
|
current_site_id = args["current_site_id"] if args.present?
|
||||||
|
|
||||||
return true if current_site_id.blank? || current_site_id == @current_db
|
return true if current_site_id.blank? || current_site_id == @current_db
|
||||||
|
@ -210,7 +210,7 @@ module Discourse
|
|||||||
return if ex.class == Jobs::HandledExceptionWrapper
|
return if ex.class == Jobs::HandledExceptionWrapper
|
||||||
|
|
||||||
context ||= {}
|
context ||= {}
|
||||||
parent_logger ||= Sidekiq
|
parent_logger ||= Sidekiq.default_configuration
|
||||||
|
|
||||||
job = context[:job]
|
job = context[:job]
|
||||||
|
|
||||||
@ -930,10 +930,7 @@ module Discourse
|
|||||||
Rails.cache.reconnect
|
Rails.cache.reconnect
|
||||||
Discourse.cache.reconnect
|
Discourse.cache.reconnect
|
||||||
Logster.store.redis.reconnect
|
Logster.store.redis.reconnect
|
||||||
# shuts down all connections in the pool
|
Sidekiq.redis_pool.reload(&:close)
|
||||||
Sidekiq.redis_pool.shutdown { |conn| conn.disconnect! }
|
|
||||||
# re-establish
|
|
||||||
Sidekiq.redis = sidekiq_redis_config
|
|
||||||
|
|
||||||
# in case v8 was initialized we want to make sure it is nil
|
# in case v8 was initialized we want to make sure it is nil
|
||||||
PrettyText.reset_context
|
PrettyText.reset_context
|
||||||
@ -1048,9 +1045,11 @@ module Discourse
|
|||||||
SIDEKIQ_NAMESPACE = "sidekiq"
|
SIDEKIQ_NAMESPACE = "sidekiq"
|
||||||
|
|
||||||
def self.sidekiq_redis_config(old: false)
|
def self.sidekiq_redis_config(old: false)
|
||||||
redis_config = GlobalSetting.redis_config.dup
|
GlobalSetting
|
||||||
return redis_config.merge(namespace: SIDEKIQ_NAMESPACE) if old
|
.redis_config
|
||||||
redis_config.merge(db: redis_config[:db].to_i + 1)
|
.dup
|
||||||
|
.except(:connector, :replica_host, :replica_port)
|
||||||
|
.tap { |config| config.merge!(db: config[:db].to_i + 1) unless old }
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.static_doc_topic_ids
|
def self.static_doc_topic_ids
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# TODO (2025-03-03): delete this once the migration is propagated everywhere
|
# TODO: Remove this after the Discourse 3.5 release
|
||||||
# (in about 6 months or so)
|
|
||||||
module Sidekiq
|
module Sidekiq
|
||||||
def self.redis_pool
|
|
||||||
@redis ||= RedisConnection.create
|
|
||||||
Thread.current[:sidekiq_via_pool] || @redis
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.old_pool
|
def self.old_pool
|
||||||
@old_pool ||= RedisConnection.create(Discourse.sidekiq_redis_config(old: true))
|
@old_pool ||=
|
||||||
|
begin
|
||||||
|
ConnectionPool.new do
|
||||||
|
Redis::Namespace.new(
|
||||||
|
Discourse::SIDEKIQ_NAMESPACE,
|
||||||
|
redis:
|
||||||
|
Sidekiq::RedisClientAdapter.new(Discourse.sidekiq_redis_config(old: true)).new_client,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SidekiqLogsterReporter
|
class SidekiqLogsterReporter
|
||||||
def call(ex, context = {})
|
def call(ex, context = {}, _config = nil)
|
||||||
return if Jobs::HandledExceptionWrapper === ex
|
return if Jobs::HandledExceptionWrapper === ex
|
||||||
Discourse.reset_active_record_cache_if_needed(ex)
|
Discourse.reset_active_record_cache_if_needed(ex)
|
||||||
|
|
||||||
|
@ -28,19 +28,18 @@ class SidekiqLongRunningJobLogger
|
|||||||
Sidekiq::Workers.new.each do |process_id, thread_id, work|
|
Sidekiq::Workers.new.each do |process_id, thread_id, work|
|
||||||
next unless process_id.start_with?(hostname)
|
next unless process_id.start_with?(hostname)
|
||||||
|
|
||||||
if Time.at(work["run_at"]).to_i >=
|
if Time.at(work.run_at).to_i >= (Time.now - (60 * @stuck_sidekiq_job_minutes)).to_i
|
||||||
(Time.now - (60 * @stuck_sidekiq_job_minutes)).to_i
|
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
jid = work.dig("payload", "jid")
|
jid = work.job.jid
|
||||||
current_long_running_jobs << jid
|
current_long_running_jobs << jid
|
||||||
|
|
||||||
next if @seen_long_running_jobs&.include?(jid)
|
next if @seen_long_running_jobs&.include?(jid)
|
||||||
|
|
||||||
if thread = Thread.list.find { |t| t["sidekiq_tid"] == thread_id }
|
if thread = Thread.list.find { |t| t["sidekiq_tid"] == thread_id }
|
||||||
Rails.logger.warn(<<~MSG)
|
Rails.logger.warn(<<~MSG)
|
||||||
Sidekiq job `#{work.dig("payload", "class")}` has been running for more than #{@stuck_sidekiq_job_minutes} minutes
|
Sidekiq job `#{work.job.klass}` has been running for more than #{@stuck_sidekiq_job_minutes} minutes
|
||||||
#{thread.backtrace.join("\n")}
|
#{thread.backtrace.join("\n")}
|
||||||
MSG
|
MSG
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# TODO (2025-03-03): delete this once the migration is propagated everywhere
|
# TODO: Remove this after the Discourse 3.5 release
|
||||||
# (in about 6 months or so)
|
|
||||||
class SidekiqMigration
|
class SidekiqMigration
|
||||||
delegate :old_pool, to: :Sidekiq
|
delegate :old_pool, to: :Sidekiq
|
||||||
|
|
||||||
|
@ -105,11 +105,7 @@ RSpec.describe BackupRestore::SystemInterface do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context "with Sidekiq workers" do
|
context "with Sidekiq workers" do
|
||||||
after { flush_sidekiq_redis_namespace }
|
after { Sidekiq.redis(&:flushdb) }
|
||||||
|
|
||||||
def flush_sidekiq_redis_namespace
|
|
||||||
Sidekiq.redis { |redis| redis.scan_each { |key| redis.del(key) } }
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_workers(site_id: nil, all_sites: false)
|
def create_workers(site_id: nil, all_sites: false)
|
||||||
payload =
|
payload =
|
||||||
@ -132,8 +128,8 @@ RSpec.describe BackupRestore::SystemInterface do
|
|||||||
key = "#{hostname}:#{pid}"
|
key = "#{hostname}:#{pid}"
|
||||||
process = { pid: pid, hostname: hostname }
|
process = { pid: pid, hostname: hostname }
|
||||||
|
|
||||||
conn.sadd?("processes", key)
|
conn.sadd("processes", key)
|
||||||
conn.hmset(key, "info", Sidekiq.dump_json(process))
|
conn.hset(key, "info", Sidekiq.dump_json(process))
|
||||||
|
|
||||||
data =
|
data =
|
||||||
Sidekiq.dump_json(
|
Sidekiq.dump_json(
|
||||||
@ -141,7 +137,7 @@ RSpec.describe BackupRestore::SystemInterface do
|
|||||||
run_at: Time.now.to_i,
|
run_at: Time.now.to_i,
|
||||||
payload: Sidekiq.dump_json(payload),
|
payload: Sidekiq.dump_json(payload),
|
||||||
)
|
)
|
||||||
conn.hmset("#{key}:work", "444", data)
|
conn.hset("#{key}:work", "444", data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ RSpec.describe Discourse do
|
|||||||
class TempSidekiqLogger
|
class TempSidekiqLogger
|
||||||
attr_accessor :exception, :context
|
attr_accessor :exception, :context
|
||||||
|
|
||||||
def call(ex, ctx)
|
def call(ex, ctx, _config)
|
||||||
self.exception = ex
|
self.exception = ex
|
||||||
self.context = ctx
|
self.context = ctx
|
||||||
end
|
end
|
||||||
@ -370,9 +370,9 @@ RSpec.describe Discourse do
|
|||||||
|
|
||||||
let!(:logger) { TempSidekiqLogger.new }
|
let!(:logger) { TempSidekiqLogger.new }
|
||||||
|
|
||||||
before { Sidekiq.error_handlers << logger }
|
before { Sidekiq.default_configuration.error_handlers << logger }
|
||||||
|
|
||||||
after { Sidekiq.error_handlers.delete(logger) }
|
after { Sidekiq.default_configuration.error_handlers.delete(logger) }
|
||||||
|
|
||||||
describe "#job_exception_stats" do
|
describe "#job_exception_stats" do
|
||||||
class FakeTestError < StandardError
|
class FakeTestError < StandardError
|
||||||
|
@ -20,24 +20,26 @@ RSpec.describe SidekiqLongRunningJobLogger do
|
|||||||
[
|
[
|
||||||
"#{hostname}:1234",
|
"#{hostname}:1234",
|
||||||
"some_sidekiq_id",
|
"some_sidekiq_id",
|
||||||
{
|
Sidekiq::Work.new(
|
||||||
"run_at" => (Time.now - (60 * (stuck_sidekiq_job_minutes + 1))).to_i,
|
"#{hostname}:1234",
|
||||||
"payload" => {
|
"some_sidekiq_id",
|
||||||
"jid" => "job_1",
|
{
|
||||||
"class" => "TestWorker",
|
"run_at" => (Time.now - (60 * (stuck_sidekiq_job_minutes + 1))).to_i,
|
||||||
|
"payload" => Sidekiq.dump_json({ "jid" => "job_1", "class" => "TestWorker" }),
|
||||||
},
|
},
|
||||||
},
|
),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"#{hostname}:1234",
|
"#{hostname}:1234",
|
||||||
"some_other_sidekiq_id",
|
"some_other_sidekiq_id",
|
||||||
{
|
Sidekiq::Work.new(
|
||||||
"run_at" => Time.now.to_i,
|
"#{hostname}:1234",
|
||||||
"payload" => {
|
"some_other_sidekiq_id",
|
||||||
"jid" => "job_2",
|
{
|
||||||
"class" => "AnotherWorker",
|
"run_at" => Time.now.to_i,
|
||||||
|
"payload" => Sidekiq.dump_json({ "jid" => "job_2", "class" => "AnotherWorker" }),
|
||||||
},
|
},
|
||||||
},
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -288,7 +288,7 @@ RSpec.configure do |config|
|
|||||||
raise "There are pending migrations, run RAILS_ENV=test bin/rake db:migrate"
|
raise "There are pending migrations, run RAILS_ENV=test bin/rake db:migrate"
|
||||||
end
|
end
|
||||||
|
|
||||||
Sidekiq.error_handlers.clear
|
Sidekiq.default_configuration.error_handlers.clear
|
||||||
|
|
||||||
# Ugly, but needed until we have a user creator
|
# Ugly, but needed until we have a user creator
|
||||||
User.skip_callback(:create, :after, :ensure_in_trust_level_group)
|
User.skip_callback(:create, :after, :ensure_in_trust_level_group)
|
||||||
|
Reference in New Issue
Block a user