Commit 74883adc authored by Sean McGivern's avatar Sean McGivern

Merge branch '1333-add-gitlab-redis-session-redis-instance' into 'master'

Add Gitlab::Redis::Sessions Redis instance

See merge request gitlab-org/gitlab!72221
parents 1ec7ca07 c4965142
......@@ -20,7 +20,8 @@ class Admin::DashboardController < Admin::ApplicationController
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
......
......@@ -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
......
......@@ -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:
......
......@@ -25,6 +25,7 @@ module Gitlab
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')
......
......@@ -18,3 +18,4 @@ Gitlab::Redis::Queues.with { nil }
Gitlab::Redis::SharedState.with { nil }
Gitlab::Redis::TraceChunks.with { nil }
Gitlab::Redis::RateLimiting.with { nil }
Gitlab::Redis::Sessions.with { nil }
......@@ -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.
......
......@@ -22,7 +22,8 @@ module Gitlab
::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
......
# 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
......@@ -10,8 +10,9 @@ module Gitlab
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
......
# 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
......@@ -18,6 +18,7 @@ RSpec.describe Gitlab::HealthChecks::Probes::Collection do
Gitlab::HealthChecks::Redis::SharedStateCheck,
Gitlab::HealthChecks::Redis::TraceChunksCheck,
Gitlab::HealthChecks::Redis::RateLimitingCheck,
Gitlab::HealthChecks::Redis::SessionsCheck,
Gitlab::HealthChecks::GitalyCheck
]
end
......
# 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
......@@ -77,7 +77,8 @@ RSpec.describe Gitlab::Instrumentation::Redis do
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
......@@ -3,53 +3,5 @@
require 'spec_helper'
RSpec.describe Gitlab::Redis::RateLimiting do
let(:instance_specific_config_file) { "config/redis.rate_limiting.yml" }
let(:environment_config_file_name) { "GITLAB_REDIS_RATE_LIMITING_CONFIG_FILE" }
let(:cache_config_file) { nil }
before do
allow(Gitlab::Redis::Cache).to receive(:config_file_name).and_return(cache_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 Cache has a different config file' do
let(:cache_config_file) { 'cache config file' }
it { expect(subject).to eq('cache config file') }
end
end
end
end
include_examples "redis_new_instance_shared_examples", 'rate_limiting', Gitlab::Redis::Cache
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Redis::Sessions do
include_examples "redis_new_instance_shared_examples", 'sessions', Gitlab::Redis::SharedState
end
......@@ -3,53 +3,5 @@
require 'spec_helper'
RSpec.describe Gitlab::Redis::TraceChunks do
let(:instance_specific_config_file) { "config/redis.trace_chunks.yml" }
let(:environment_config_file_name) { "GITLAB_REDIS_TRACE_CHUNKS_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
include_examples "redis_new_instance_shared_examples", 'trace_chunks', Gitlab::Redis::SharedState
end
......@@ -46,4 +46,12 @@ RSpec.configure do |config|
redis_rate_limiting_cleanup!
end
config.around(:each, :clean_gitlab_redis_sessions) do |example|
redis_sessions_cleanup!
example.run
redis_sessions_cleanup!
end
end
......@@ -27,4 +27,9 @@ module RedisHelpers
def redis_rate_limiting_cleanup!
Gitlab::Redis::RateLimiting.with(&:flushdb)
end
# Usage: session state
def redis_sessions_cleanup!
Gitlab::Redis::Sessions.with(&:flushdb)
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.shared_examples "redis_new_instance_shared_examples" do |name, fallback_class|
let(:instance_specific_config_file) { "config/redis.#{name}.yml" }
let(:environment_config_file_name) { "GITLAB_REDIS_#{name.upcase}_CONFIG_FILE" }
let(:fallback_config_file) { nil }
before do
allow(fallback_class).to receive(:config_file_name).and_return(fallback_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 #{fallback_class.name.demodulize} has a different config file" do
let(:fallback_config_file) { 'fallback config file' }
it { expect(subject).to eq('fallback config file') }
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment