Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-12-07 21:09:16 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-07 21:09:16 +0300
commit38e6d9291369e346f33f52a5ab656b787ce0a2c0 (patch)
treec5137121d6cc0ff5d9372252569c10a05164b794 /lib/gitlab/instrumentation
parent2a501f63df96252295df7efe53880c5e78fa22b5 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/instrumentation')
-rw-r--r--lib/gitlab/instrumentation/redis_base.rb22
-rw-r--r--lib/gitlab/instrumentation/redis_cluster_validator.rb15
2 files changed, 27 insertions, 10 deletions
diff --git a/lib/gitlab/instrumentation/redis_base.rb b/lib/gitlab/instrumentation/redis_base.rb
index 91ee5885ed2..4f27fce43a4 100644
--- a/lib/gitlab/instrumentation/redis_base.rb
+++ b/lib/gitlab/instrumentation/redis_base.rb
@@ -5,6 +5,8 @@ require 'redis'
module Gitlab
module Instrumentation
class RedisBase
+ VALIDATE_ALLOWED_COMMANDS_KEY = 'validate_allowed_commands_flag'
+
class << self
include ::Gitlab::Utils::StrongMemoize
include ::Gitlab::Instrumentation::RedisPayload
@@ -75,13 +77,23 @@ module Gitlab
query_time.round(::Gitlab::InstrumentationHelper::DURATION_PRECISION)
end
+ def validate_allowed_commands?
+ ::Gitlab::SafeRequestStore.fetch(VALIDATE_ALLOWED_COMMANDS_KEY) do
+ Feature.enabled?(:validate_allowed_cross_slot_commands, type: :development)
+ end
+ end
+
def redis_cluster_validate!(commands)
- ::Gitlab::Instrumentation::RedisClusterValidator.validate!(commands) if @redis_cluster_validation
- true
- rescue ::Gitlab::Instrumentation::RedisClusterValidator::CrossSlotError
- raise if Rails.env.development? || Rails.env.test? # raise in test environments to catch violations
+ return true unless @redis_cluster_validation
+
+ result = ::Gitlab::Instrumentation::RedisClusterValidator.validate(commands, validate_allowed_commands?)
+ return true if result.nil?
+
+ if !result[:valid] && !result[:allowed] && (Rails.env.development? || Rails.env.test?)
+ raise RedisClusterValidator::CrossSlotError, "Redis command #{result[:command_name]} arguments hash to different slots. See https://docs.gitlab.com/ee/development/redis.html#multi-key-commands"
+ end
- false
+ result[:valid]
end
def enable_redis_cluster_validation
diff --git a/lib/gitlab/instrumentation/redis_cluster_validator.rb b/lib/gitlab/instrumentation/redis_cluster_validator.rb
index a928d626f38..ad715574ec2 100644
--- a/lib/gitlab/instrumentation/redis_cluster_validator.rb
+++ b/lib/gitlab/instrumentation/redis_cluster_validator.rb
@@ -183,8 +183,8 @@ module Gitlab
CrossSlotError = Class.new(StandardError)
class << self
- def validate!(commands)
- return if allow_cross_slot_commands?
+ def validate(commands, validate_allowed_cmd)
+ return if allow_cross_slot_commands? && !validate_allowed_cmd
return if commands.empty?
# early exit for single-command (non-pipelined) if it is a single-key-command
@@ -192,9 +192,14 @@ module Gitlab
return if commands.size == 1 && REDIS_COMMANDS.dig(command_name, :single_key)
key_slots = commands.map { |command| key_slots(command) }.flatten
- if key_slots.uniq.many? # rubocop: disable CodeReuse/ActiveRecord
- raise CrossSlotError, "Redis command #{command_name} arguments hash to different slots. See https://docs.gitlab.com/ee/development/redis.html#multi-key-commands"
- end
+
+ {
+ valid: !key_slots.uniq.many?, # rubocop: disable CodeReuse/ActiveRecord
+ command_name: command_name,
+ key_count: key_slots.size,
+ allowed: allow_cross_slot_commands?,
+ command: commands.first.join(' ')
+ }
end
# Keep track of the call stack to allow nested calls to work.