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:
Diffstat (limited to 'lib/gitlab/redis')
-rw-r--r--lib/gitlab/redis/multi_store.rb52
-rw-r--r--lib/gitlab/redis/sessions.rb42
-rw-r--r--lib/gitlab/redis/sessions_store_helper.rb27
-rw-r--r--lib/gitlab/redis/shared_state.rb4
-rw-r--r--lib/gitlab/redis/wrapper.rb12
5 files changed, 110 insertions, 27 deletions
diff --git a/lib/gitlab/redis/multi_store.rb b/lib/gitlab/redis/multi_store.rb
index f930a0040bc..500b62bf0e8 100644
--- a/lib/gitlab/redis/multi_store.rb
+++ b/lib/gitlab/redis/multi_store.rb
@@ -21,6 +21,8 @@ module Gitlab
FAILED_TO_READ_ERROR_MESSAGE = 'Failed to read from the redis primary_store.'
FAILED_TO_WRITE_ERROR_MESSAGE = 'Failed to write to the redis primary_store.'
+ SKIP_LOG_METHOD_MISSING_FOR_COMMANDS = %i(info).freeze
+
READ_COMMANDS = %i(
get
mget
@@ -39,41 +41,42 @@ module Gitlab
flushdb
).freeze
- def initialize(primary_store, secondary_store, instance_name = nil)
+ def initialize(primary_store, secondary_store, instance_name)
@primary_store = primary_store
@secondary_store = secondary_store
@instance_name = instance_name
validate_stores!
end
-
+ # rubocop:disable GitlabSecurity/PublicSend
READ_COMMANDS.each do |name|
define_method(name) do |*args, &block|
- if multi_store_enabled?
+ if use_primary_and_secondary_stores?
read_command(name, *args, &block)
else
- secondary_store.send(name, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
+ default_store.send(name, *args, &block)
end
end
end
WRITE_COMMANDS.each do |name|
define_method(name) do |*args, &block|
- if multi_store_enabled?
+ if use_primary_and_secondary_stores?
write_command(name, *args, &block)
else
- secondary_store.send(name, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
+ default_store.send(name, *args, &block)
end
end
end
def method_missing(...)
- return @instance.send(...) if @instance # rubocop:disable GitlabSecurity/PublicSend
+ return @instance.send(...) if @instance
log_method_missing(...)
- secondary_store.send(...) # rubocop:disable GitlabSecurity/PublicSend
+ default_store.send(...)
end
+ # rubocop:enable GitlabSecurity/PublicSend
def respond_to_missing?(command_name, include_private = false)
true
@@ -83,23 +86,37 @@ module Gitlab
# https://github.com/redis-store/redis-rack/blob/a833086ba494083b6a384a1a4e58b36573a9165d/lib/redis/rack/connection.rb#L15
# Done similarly in https://github.com/lsegal/yard/blob/main/lib/yard/templates/template.rb#L122
def is_a?(klass)
- return true if klass == secondary_store.class
+ return true if klass == default_store.class
super(klass)
end
alias_method :kind_of?, :is_a?
def to_s
- if multi_store_enabled?
- primary_store.to_s
- else
- secondary_store.to_s
- end
+ use_primary_and_secondary_stores? ? primary_store.to_s : default_store.to_s
+ end
+
+ def use_primary_and_secondary_stores?
+ feature_flags_available? &&
+ Feature.enabled?("use_primary_and_secondary_stores_for_#{instance_name.underscore}", default_enabled: :yaml) &&
+ !same_redis_store?
+ end
+
+ def use_primary_store_as_default?
+ feature_flags_available? &&
+ Feature.enabled?("use_primary_store_as_default_for_#{instance_name.underscore}", default_enabled: :yaml) &&
+ !same_redis_store?
end
private
+ def default_store
+ use_primary_store_as_default? ? primary_store : secondary_store
+ end
+
def log_method_missing(command_name, *_args)
+ return if SKIP_LOG_METHOD_MISSING_FOR_COMMANDS.include?(command_name)
+
log_error(MethodMissingError.new, command_name)
increment_method_missing_count(command_name)
end
@@ -155,10 +172,6 @@ module Gitlab
send_command(secondary_store, command_name, *args, &block)
end
- def multi_store_enabled?
- Feature.enabled?(:use_multi_store, default_enabled: :yaml) && !same_redis_store?
- end
-
def same_redis_store?
strong_memoize(:same_redis_store) do
# <Redis client v4.4.0 for redis:///path_to/redis/redis.socket/5>"
@@ -194,12 +207,13 @@ module Gitlab
def increment_method_missing_count(command_name)
@method_missing_counter ||= Gitlab::Metrics.counter(:gitlab_redis_multi_store_method_missing_total, 'Client side Redis MultiStore method missing')
- @method_missing_counter.increment(command: command_name, innamece_name: instance_name)
+ @method_missing_counter.increment(command: command_name, instance_name: instance_name)
end
def validate_stores!
raise ArgumentError, 'primary_store is required' unless primary_store
raise ArgumentError, 'secondary_store is required' unless secondary_store
+ raise ArgumentError, 'instance_name is required' unless instance_name
raise ArgumentError, 'invalid primary_store' unless primary_store.is_a?(::Redis)
raise ArgumentError, 'invalid secondary_store' unless secondary_store.is_a?(::Redis)
end
diff --git a/lib/gitlab/redis/sessions.rb b/lib/gitlab/redis/sessions.rb
index 3bf1eb6211d..c547828d907 100644
--- a/lib/gitlab/redis/sessions.rb
+++ b/lib/gitlab/redis/sessions.rb
@@ -3,9 +3,45 @@
module Gitlab
module Redis
class Sessions < ::Gitlab::Redis::Wrapper
- # The data we store on Sessions used to be stored on SharedState.
- def self.config_fallback
- SharedState
+ SESSION_NAMESPACE = 'session:gitlab'
+ USER_SESSIONS_NAMESPACE = 'session:user:gitlab'
+ USER_SESSIONS_LOOKUP_NAMESPACE = 'session:lookup:user:gitlab'
+ IP_SESSIONS_LOOKUP_NAMESPACE = 'session:lookup:ip:gitlab2'
+ OTP_SESSIONS_NAMESPACE = 'session:otp'
+
+ class << self
+ # The data we store on Sessions used to be stored on SharedState.
+ def config_fallback
+ SharedState
+ end
+
+ private
+
+ def redis
+ # Don't use multistore if redis.sessions configuration is not provided
+ return super if config_fallback?
+
+ primary_store = ::Redis.new(params)
+ secondary_store = ::Redis.new(config_fallback.params)
+
+ MultiStore.new(primary_store, secondary_store, store_name)
+ end
+ end
+
+ def store(extras = {})
+ # Don't use multistore if redis.sessions configuration is not provided
+ return super if self.class.config_fallback?
+
+ primary_store = create_redis_store(redis_store_options, extras)
+ secondary_store = create_redis_store(self.class.config_fallback.params, extras)
+
+ MultiStore.new(primary_store, secondary_store, self.class.store_name)
+ end
+
+ private
+
+ def create_redis_store(options, extras)
+ ::Redis::Store.new(options.merge(extras))
end
end
end
diff --git a/lib/gitlab/redis/sessions_store_helper.rb b/lib/gitlab/redis/sessions_store_helper.rb
new file mode 100644
index 00000000000..c80442847f1
--- /dev/null
+++ b/lib/gitlab/redis/sessions_store_helper.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Redis
+ module SessionsStoreHelper
+ extend ActiveSupport::Concern
+
+ module StoreMethods
+ def redis_store_class
+ use_redis_session_store? ? Gitlab::Redis::Sessions : Gitlab::Redis::SharedState
+ end
+
+ private
+
+ def use_redis_session_store?
+ Gitlab::Utils.to_boolean(ENV['GITLAB_USE_REDIS_SESSIONS_STORE'], default: true)
+ end
+ end
+
+ include StoreMethods
+
+ included do
+ extend StoreMethods
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/redis/shared_state.rb b/lib/gitlab/redis/shared_state.rb
index 1250eabb041..fb3a143121b 100644
--- a/lib/gitlab/redis/shared_state.rb
+++ b/lib/gitlab/redis/shared_state.rb
@@ -3,10 +3,6 @@
module Gitlab
module Redis
class SharedState < ::Gitlab::Redis::Wrapper
- SESSION_NAMESPACE = 'session:gitlab'
- USER_SESSIONS_NAMESPACE = 'session:user:gitlab'
- USER_SESSIONS_LOOKUP_NAMESPACE = 'session:lookup:user:gitlab'
- IP_SESSIONS_LOOKUP_NAMESPACE = 'session:lookup:ip:gitlab2'
end
end
end
diff --git a/lib/gitlab/redis/wrapper.rb b/lib/gitlab/redis/wrapper.rb
index 985c8dc619c..75dbccb965d 100644
--- a/lib/gitlab/redis/wrapper.rb
+++ b/lib/gitlab/redis/wrapper.rb
@@ -28,7 +28,7 @@ module Gitlab
end
def pool
- @pool ||= ConnectionPool.new(size: pool_size) { ::Redis.new(params) }
+ @pool ||= ConnectionPool.new(size: pool_size) { redis }
end
def pool_size
@@ -67,6 +67,10 @@ module Gitlab
File.expand_path('../../..', __dir__)
end
+ def config_fallback?
+ config_file_name == config_fallback&.config_file_name
+ end
+
def config_file_name
[
# Instance specific config sources:
@@ -100,6 +104,12 @@ module Gitlab
"::Gitlab::Instrumentation::Redis::#{store_name}".constantize
end
+
+ private
+
+ def redis
+ ::Redis.new(params)
+ end
end
def initialize(rails_env = nil)