summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-09-06 03:12:08 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-06 03:12:08 +0000
commit091f92820381bde259de3d33571ee5102d54cb01 (patch)
treebac19e61eff6f97b1370d794a45ebf22faa826c0 /lib
parentf48ded4221ac830ff354693740cf919052359e00 (diff)
downloadgitlab-ce-091f92820381bde259de3d33571ee5102d54cb01.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/instrumentation/redis_base.rb14
-rw-r--r--lib/gitlab/instrumentation/redis_interceptor.rb57
-rw-r--r--lib/gitlab/reactive_cache_set_cache.rb6
-rw-r--r--lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb10
-rw-r--r--lib/peek/views/redis_detailed.rb6
-rw-r--r--lib/tasks/gitlab/db/validate_config.rake2
6 files changed, 56 insertions, 39 deletions
diff --git a/lib/gitlab/instrumentation/redis_base.rb b/lib/gitlab/instrumentation/redis_base.rb
index 0beab008f73..0bd10597f24 100644
--- a/lib/gitlab/instrumentation/redis_base.rb
+++ b/lib/gitlab/instrumentation/redis_base.rb
@@ -20,21 +20,19 @@ module Gitlab
::RequestStore[call_duration_key] += duration
end
- def add_call_details(duration, args)
+ def add_call_details(duration, commands)
return unless Gitlab::PerformanceBar.enabled_for_request?
- # redis-rb passes an array (e.g. [[:get, key]])
- return unless args.length == 1
detail_store << {
- cmd: args.first,
+ commands: commands,
duration: duration,
backtrace: ::Gitlab::BacktraceCleaner.clean_backtrace(caller)
}
end
- def increment_request_count
+ def increment_request_count(amount = 1)
::RequestStore[request_count_key] ||= 0
- ::RequestStore[request_count_key] += 1
+ ::RequestStore[request_count_key] += amount
end
def increment_read_bytes(num_bytes)
@@ -78,9 +76,9 @@ module Gitlab
self
end
- def instance_count_request
+ def instance_count_request(amount = 1)
@request_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_requests_total, 'Client side Redis request count, per Redis server')
- @request_counter.increment({ storage: storage_key })
+ @request_counter.increment({ storage: storage_key }, amount)
end
def instance_count_exception(ex)
diff --git a/lib/gitlab/instrumentation/redis_interceptor.rb b/lib/gitlab/instrumentation/redis_interceptor.rb
index 14474693ddf..7e2acb91b94 100644
--- a/lib/gitlab/instrumentation/redis_interceptor.rb
+++ b/lib/gitlab/instrumentation/redis_interceptor.rb
@@ -13,27 +13,15 @@ module Gitlab
end
end
- def call(*args, &block)
- start = Gitlab::Metrics::System.monotonic_time # must come first so that 'start' is always defined
- instrumentation_class.instance_count_request
- instrumentation_class.redis_cluster_validate!(args.first)
-
- super(*args, &block)
- rescue ::Redis::BaseError => ex
- instrumentation_class.instance_count_exception(ex)
- raise ex
- ensure
- duration = Gitlab::Metrics::System.monotonic_time - start
-
- unless APDEX_EXCLUDE.include?(command_from_args(args))
- instrumentation_class.instance_observe_duration(duration)
+ def call(command)
+ instrument_call([command]) do
+ super
end
+ end
- if ::RequestStore.active?
- # These metrics measure total Redis usage per Rails request / job.
- instrumentation_class.increment_request_count
- instrumentation_class.add_duration(duration)
- instrumentation_class.add_call_details(duration, args)
+ def call_pipeline(pipeline)
+ instrument_call(pipeline.commands) do
+ super
end
end
@@ -50,6 +38,31 @@ module Gitlab
private
+ def instrument_call(commands)
+ start = Gitlab::Metrics::System.monotonic_time # must come first so that 'start' is always defined
+ instrumentation_class.instance_count_request(commands.size)
+
+ commands.each { |c| instrumentation_class.redis_cluster_validate!(c) }
+
+ yield
+ rescue ::Redis::BaseError => ex
+ instrumentation_class.instance_count_exception(ex)
+ raise ex
+ ensure
+ duration = Gitlab::Metrics::System.monotonic_time - start
+
+ unless exclude_from_apdex?(commands)
+ commands.each { instrumentation_class.instance_observe_duration(duration / commands.size) }
+ end
+
+ if ::RequestStore.active?
+ # These metrics measure total Redis usage per Rails request / job.
+ instrumentation_class.increment_request_count(commands.size)
+ instrumentation_class.add_duration(duration)
+ instrumentation_class.add_call_details(duration, commands)
+ end
+ end
+
def measure_write_size(command)
size = 0
@@ -97,10 +110,8 @@ module Gitlab
@options[:instrumentation_class] # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
- def command_from_args(args)
- command = args[0]
- command = command[0] if command.is_a?(Array)
- command.to_s.downcase
+ def exclude_from_apdex?(commands)
+ commands.any? { |command| APDEX_EXCLUDE.include?(command.first.to_s.downcase) }
end
end
end
diff --git a/lib/gitlab/reactive_cache_set_cache.rb b/lib/gitlab/reactive_cache_set_cache.rb
index fbf96023f30..2de3c07712f 100644
--- a/lib/gitlab/reactive_cache_set_cache.rb
+++ b/lib/gitlab/reactive_cache_set_cache.rb
@@ -15,8 +15,10 @@ module Gitlab
keys = read(key).map { |value| "#{cache_namespace}:#{value}" }
keys << cache_key(key)
- redis.pipelined do |pipeline|
- keys.each_slice(1000) { |subset| pipeline.unlink(*subset) }
+ Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ redis.pipelined do |pipeline|
+ keys.each_slice(1000) { |subset| pipeline.unlink(*subset) }
+ end
end
end
end
diff --git a/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb b/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
index 7533770e254..ab126ea4749 100644
--- a/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
+++ b/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
@@ -112,10 +112,12 @@ module Gitlab
end
def delete!
- with_redis do |redis|
- redis.multi do |multi|
- multi.del(idempotency_key, deduplicated_flag_key)
- delete_wal_locations!(multi)
+ Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ with_redis do |redis|
+ redis.multi do |multi|
+ multi.del(idempotency_key, deduplicated_flag_key)
+ delete_wal_locations!(multi)
+ end
end
end
end
diff --git a/lib/peek/views/redis_detailed.rb b/lib/peek/views/redis_detailed.rb
index 44ec0ec0f68..76c283bf802 100644
--- a/lib/peek/views/redis_detailed.rb
+++ b/lib/peek/views/redis_detailed.rb
@@ -16,7 +16,11 @@ module Peek
private
def format_call_details(call)
- super.merge(cmd: format_command(call[:cmd]),
+ cmd = call[:commands].map do |command|
+ format_command(command)
+ end.join(', ')
+
+ super.merge(cmd: cmd,
instance: call[:storage])
end
diff --git a/lib/tasks/gitlab/db/validate_config.rake b/lib/tasks/gitlab/db/validate_config.rake
index 2a3a54b5351..bf9ebc56486 100644
--- a/lib/tasks/gitlab/db/validate_config.rake
+++ b/lib/tasks/gitlab/db/validate_config.rake
@@ -144,7 +144,7 @@ namespace :gitlab do
rescue ActiveRecord::StatementInvalid => err
raise unless err.cause.is_a?(PG::ReadOnlySqlTransaction)
- warn "WARNING: Could not write to the database #{db_config.name}: #{err.message}"
+ warn "WARNING: Could not write to the database #{db_config.name}: cannot execute UPSERT in a read-only transaction"
end
def get_db_identifier(db_config)