Add Gitlab::Redis::Sessions Redis instance

This instance is not used yet, but will soon be used for sessions
via ActiveSession. Having this
configuration option in place will allow us to build on that, and also
create merge requests to support this option in Omnibus and our Helm
charts.
This commit is contained in:
nmilojevic1 2021-10-12 16:11:27 +02:00
parent 80746ab8b9
commit fb810acec4
16 changed files with 137 additions and 4 deletions

View file

@ -20,7 +20,8 @@ def index
Gitlab::Redis::SharedState,
Gitlab::Redis::Cache,
Gitlab::Redis::TraceChunks,
Gitlab::Redis::RateLimiting
Gitlab::Redis::RateLimiting,
Gitlab::Redis::Sessions
].map(&:version).uniq
end
# rubocop: enable CodeReuse/ActiveRecord

View file

@ -17,6 +17,7 @@ class HealthController < ActionController::Base
Gitlab::HealthChecks::Redis::SharedStateCheck,
Gitlab::HealthChecks::Redis::TraceChunksCheck,
Gitlab::HealthChecks::Redis::RateLimitingCheck,
Gitlab::HealthChecks::Redis::SessionsCheck,
Gitlab::HealthChecks::GitalyCheck
].freeze

View file

@ -78,6 +78,7 @@ An example configuration file for Redis is in this directory under the name
| `shared_state` | | Persistent application state |
| `trace_chunks` | `shared_state` | [CI trace chunks](https://docs.gitlab.com/ee/administration/job_logs.html#incremental-logging-architecture) |
| `rate_limiting` | `cache` | [Rate limiting](https://docs.gitlab.com/ee/user/admin_area/settings/user_and_ip_rate_limits.html) state |
| `sessions` | `shared_state` | [Sessions](https://docs.gitlab.com/ee/development/session.html#redis)|
If no configuration is found, or no URL is found in the configuration
file, the default URL used is:

View file

@ -25,6 +25,7 @@ class Application < Rails::Application
require_dependency Rails.root.join('lib/gitlab/redis/shared_state')
require_dependency Rails.root.join('lib/gitlab/redis/trace_chunks')
require_dependency Rails.root.join('lib/gitlab/redis/rate_limiting')
require_dependency Rails.root.join('lib/gitlab/redis/sessions')
require_dependency Rails.root.join('lib/gitlab/current_settings')
require_dependency Rails.root.join('lib/gitlab/middleware/read_only')
require_dependency Rails.root.join('lib/gitlab/middleware/basic_health_check')

View file

@ -18,3 +18,4 @@
Gitlab::Redis::SharedState.with { nil }
Gitlab::Redis::TraceChunks.with { nil }
Gitlab::Redis::RateLimiting.with { nil }
Gitlab::Redis::Sessions.with { nil }

View file

@ -16,6 +16,7 @@ GitLab uses [Redis](https://redis.io) for the following distinct purposes:
- To store CI trace chunks.
- As a Pub/Sub queue backend for ActionCable.
- Rate limiting state storage.
- Sessions
In most environments (including the GDK), all of these point to the same
Redis instance.

View file

@ -22,7 +22,8 @@ def check
::Gitlab::HealthChecks::Redis::QueuesCheck.check_up &&
::Gitlab::HealthChecks::Redis::SharedStateCheck.check_up &&
::Gitlab::HealthChecks::Redis::TraceChunksCheck.check_up &&
::Gitlab::HealthChecks::Redis::RateLimitingCheck.check_up
::Gitlab::HealthChecks::Redis::RateLimitingCheck.check_up &&
::Gitlab::HealthChecks::Redis::SessionsCheck.check_up
end
end
end

View file

@ -0,0 +1,35 @@
# frozen_string_literal: true
module Gitlab
module HealthChecks
module Redis
class SessionsCheck
extend SimpleAbstractCheck
class << self
def check_up
check
end
private
def metric_prefix
'redis_sessions_ping'
end
def successful?(result)
result == 'PONG'
end
# rubocop: disable CodeReuse/ActiveRecord
def check
catch_timeout 10.seconds do
Gitlab::Redis::Sessions.with(&:ping)
end
end
# rubocop: enable CodeReuse/ActiveRecord
end
end
end
end
end

View file

@ -10,8 +10,9 @@ class Redis
SharedState = Class.new(RedisBase).enable_redis_cluster_validation
TraceChunks = Class.new(RedisBase).enable_redis_cluster_validation
RateLimiting = Class.new(RedisBase).enable_redis_cluster_validation
Sessions = Class.new(RedisBase).enable_redis_cluster_validation
STORAGES = [ActionCable, Cache, Queues, SharedState, TraceChunks, RateLimiting].freeze
STORAGES = [ActionCable, Cache, Queues, SharedState, TraceChunks, RateLimiting, Sessions].freeze
# Milliseconds represented in seconds (from 1 millisecond to 2 seconds).
QUERY_TIME_BUCKETS = [0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2].freeze

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
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
end
end
end
end

View file

@ -18,6 +18,7 @@
Gitlab::HealthChecks::Redis::SharedStateCheck,
Gitlab::HealthChecks::Redis::TraceChunksCheck,
Gitlab::HealthChecks::Redis::RateLimitingCheck,
Gitlab::HealthChecks::Redis::SessionsCheck,
Gitlab::HealthChecks::GitalyCheck
]
end

View file

@ -0,0 +1,8 @@
# frozen_string_literal: true
require 'spec_helper'
require_relative '../simple_check_shared'
RSpec.describe Gitlab::HealthChecks::Redis::SessionsCheck do
include_examples 'simple_check', 'redis_sessions_ping', 'RedisSessions', 'PONG'
end

View file

@ -77,7 +77,8 @@ def stub_storages(method, value)
details_row.merge(storage: 'Queues'),
details_row.merge(storage: 'SharedState'),
details_row.merge(storage: 'TraceChunks'),
details_row.merge(storage: 'RateLimiting'))
details_row.merge(storage: 'RateLimiting'),
details_row.merge(storage: 'Sessions'))
end
end
end

View file

@ -0,0 +1,55 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Redis::Sessions do
let(:instance_specific_config_file) { "config/redis.sessions.yml" }
let(:environment_config_file_name) { "GITLAB_REDIS_SESSIONS_CONFIG_FILE" }
let(:shared_state_config_file) { nil }
before do
allow(Gitlab::Redis::SharedState).to receive(:config_file_name).and_return(shared_state_config_file)
end
include_examples "redis_shared_examples"
describe '.config_file_name' do
subject { described_class.config_file_name }
let(:rails_root) { Dir.mktmpdir('redis_shared_examples') }
before do
# Undo top-level stub of config_file_name because we are testing that method now.
allow(described_class).to receive(:config_file_name).and_call_original
allow(described_class).to receive(:rails_root).and_return(rails_root)
FileUtils.mkdir_p(File.join(rails_root, 'config'))
end
after do
FileUtils.rm_rf(rails_root)
end
context 'when there is only a resque.yml' do
before do
FileUtils.touch(File.join(rails_root, 'config/resque.yml'))
end
it { expect(subject).to eq("#{rails_root}/config/resque.yml") }
context 'and there is a global env override' do
before do
stub_env('GITLAB_REDIS_CONFIG_FILE', 'global override')
end
it { expect(subject).to eq('global override') }
context 'and SharedState has a different config file' do
let(:shared_state_config_file) { 'shared state config file' }
it { expect(subject).to eq('shared state config file') }
end
end
end
end
end

View file

@ -46,4 +46,12 @@
redis_rate_limiting_cleanup!
end
config.around(:each, :clean_gitlab_redis_sessions) do |example|
redis_sessions_cleanup!
example.run
redis_sessions_cleanup!
end
end

View file

@ -27,4 +27,9 @@ def redis_trace_chunks_cleanup!
def redis_rate_limiting_cleanup!
Gitlab::Redis::RateLimiting.with(&:flushdb)
end
# Usage: session state
def redis_sessions_cleanup!
Gitlab::Redis::Session.with(&:flushdb)
end
end