Commit 97611c88 authored by Rémy Coutable's avatar Rémy Coutable

Don't use Flipper for the Performance Bar

The implementation now simply rely on the
`performance_bar_allowed_group_id` Application Setting.
Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parent 040eeb10
...@@ -338,39 +338,45 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -338,39 +338,45 @@ class ApplicationSetting < ActiveRecord::Base
end end
def performance_bar_allowed_group_id=(group_full_path) def performance_bar_allowed_group_id=(group_full_path)
group_full_path = nil if group_full_path.blank?
if group_full_path.nil?
if group_full_path != performance_bar_allowed_group_id
super(group_full_path)
Gitlab::PerformanceBar.expire_allowed_user_ids_cache
end
return
end
group = Group.find_by_full_path(group_full_path) group = Group.find_by_full_path(group_full_path)
return unless group && group.id != performance_bar_allowed_group_id
super(group.id) if group
Gitlab::PerformanceBar.expire_allowed_user_ids_cache if group.id != performance_bar_allowed_group_id
super(group.id)
Gitlab::PerformanceBar.expire_allowed_user_ids_cache
end
else
super(nil)
Gitlab::PerformanceBar.expire_allowed_user_ids_cache
end
end end
def performance_bar_allowed_group def performance_bar_allowed_group
Group.find_by_id(performance_bar_allowed_group_id) Group.find_by_id(performance_bar_allowed_group_id)
end end
# Return true is the Performance Bar is available globally or for the # Return true if the Performance Bar is enabled for a given group
# `performance_team` feature group def performance_bar_enabled
def performance_bar_enabled? performance_bar_allowed_group_id.present?
feature = Feature.get(:performance_bar)
feature.on? || feature.groups_value.include?('performance_team')
end end
# - If `enable` is true, enable the `performance_bar` feature for the # - If `enable` is true, we early return since the actual attribute that holds
# `performance_team` feature group # the enabling/disabling is `performance_bar_allowed_group_id`
# - If `enable` is false, disable the `performance_bar` feature globally # - If `enable` is false, we set `performance_bar_allowed_group_id` to `nil`
def performance_bar_enabled=(enable) def performance_bar_enabled=(enable)
feature = Feature.get(:performance_bar) return if enable
performance_bar_on = performance_bar_enabled?
if enable && !performance_bar_on self.performance_bar_allowed_group_id = nil
feature.enable_group(:performance_team)
Gitlab::PerformanceBar.expire_allowed_user_ids_cache
elsif !enable && performance_bar_on
feature.disable
Gitlab::PerformanceBar.expire_allowed_user_ids_cache
end
end end
# Choose one of the available repository storage options. Currently all have # Choose one of the available repository storage options. Currently all have
......
...@@ -3,6 +3,4 @@ require 'flipper/middleware/memoizer' ...@@ -3,6 +3,4 @@ require 'flipper/middleware/memoizer'
unless Rails.env.test? unless Rails.env.test?
Rails.application.config.middleware.use Flipper::Middleware::Memoizer, Rails.application.config.middleware.use Flipper::Middleware::Memoizer,
lambda { Feature.flipper } lambda { Feature.flipper }
Feature.register_feature_groups
end end
...@@ -33,31 +33,3 @@ Make sure _Enable the Performance Bar_ is checked and hit ...@@ -33,31 +33,3 @@ Make sure _Enable the Performance Bar_ is checked and hit
![GitLab Performance Bar Admin Settings](img/performance_bar_configuration_settings.png) ![GitLab Performance Bar Admin Settings](img/performance_bar_configuration_settings.png)
--- ---
## Enable the Performance Bar via the API
Under the hood, the Performance Bar activation is done via the `performance_bar`
[Feature Flag](../../../development/features_flags.md).
That means you can also enable or disable it via the
[Features API](../../../api/features.md#set-or-create-a-feature).
### For the `performance_team` feature group
The `performance_team` feature group maps to the group specified in your [Admin
area](#enable-the-performance-bar-via-the-admin-panel).
```
curl --data "feature_group=performance_team" --data "value=true" --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/features/performance_bar
```
### For specific users
It's also possible to enable the Performance Bar for specific users in addition
to a group, or even instead of a group:
```
curl --data "user=my_username" --data "value=true" --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/features/performance_bar
```
[reconfigure]: ../../restart_gitlab.md#omnibus-gitlab-reconfigure
...@@ -15,8 +15,7 @@ Starting from GitLab 9.4 we support feature groups via ...@@ -15,8 +15,7 @@ Starting from GitLab 9.4 we support feature groups via
Feature groups must be defined statically in `lib/feature.rb` (in the Feature groups must be defined statically in `lib/feature.rb` (in the
`.register_feature_groups` method), but their implementation can obviously be `.register_feature_groups` method), but their implementation can obviously be
dynamic (querying the DB etc.). You can see how the `performance_team` feature dynamic (querying the DB etc.).
group for a concrete example.
Once defined in `lib/feature.rb`, you will be able to activate a Once defined in `lib/feature.rb`, you will be able to activate a
feature for a given feature group via the [`feature_group` param of the features API](../api/features.md#set-or-create-a-feature) feature for a given feature group via the [`feature_group` param of the features API](../api/features.md#set-or-create-a-feature)
...@@ -57,13 +57,5 @@ class Feature ...@@ -57,13 +57,5 @@ class Feature
Flipper.new(adapter) Flipper.new(adapter)
end end
end end
def register_feature_groups
Flipper.register(:performance_team) do |actor|
user = actor.thing
user&.is_a?(User) && Gitlab::PerformanceBar.allowed_user?(user)
end
end
end end
end end
...@@ -3,16 +3,9 @@ module Gitlab ...@@ -3,16 +3,9 @@ module Gitlab
include Gitlab::CurrentSettings include Gitlab::CurrentSettings
ALLOWED_USER_IDS_KEY = 'performance_bar_allowed_user_ids'.freeze ALLOWED_USER_IDS_KEY = 'performance_bar_allowed_user_ids'.freeze
# The time (in seconds) after which a set of allowed user IDs is expired
# automatically.
ALLOWED_USER_IDS_TIME_TO_LIVE = 10.minutes
def self.enabled?(current_user = nil) def self.enabled?(user = nil)
Feature.enabled?(:performance_bar, current_user) return false unless user && allowed_group_id
end
def self.allowed_user?(user)
return false unless allowed_group_id
allowed_user_ids.include?(user.id) allowed_user_ids.include?(user.id)
end end
...@@ -22,7 +15,7 @@ module Gitlab ...@@ -22,7 +15,7 @@ module Gitlab
end end
def self.allowed_user_ids def self.allowed_user_ids
Rails.cache.fetch(ALLOWED_USER_IDS_KEY, expires_in: ALLOWED_USER_IDS_TIME_TO_LIVE) do Rails.cache.fetch(ALLOWED_USER_IDS_KEY) do
group = Group.find_by_id(allowed_group_id) group = Group.find_by_id(allowed_group_id)
if group if group
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::PerformanceBar do describe Gitlab::PerformanceBar do
describe '.enabled?' do shared_examples 'allowed user IDs are cached' do
it 'returns false when given actor is nil' do
expect(described_class.enabled?(nil)).to be_falsy
end
it 'returns false when feature is disabled' do
actor = double('actor')
expect(Feature).to receive(:enabled?)
.with(:performance_bar, actor).and_return(false)
expect(described_class.enabled?(actor)).to be_falsy
end
it 'returns true when feature is enabled' do
actor = double('actor')
expect(Feature).to receive(:enabled?)
.with(:performance_bar, actor).and_return(true)
expect(described_class.enabled?(actor)).to be_truthy
end
end
shared_examples 'allowed user IDs are cached in Redis for 10 minutes' do
before do before do
# Warm the Redis cache # Warm the Redis cache
described_class.allowed_user?(user) described_class.enabled?(user)
end end
it 'caches the allowed user IDs in cache', :caching do it 'caches the allowed user IDs in cache', :caching do
expect do expect do
expect(described_class.allowed_user?(user)).to be_truthy expect(described_class.enabled?(user)).to be_truthy
end.not_to exceed_query_limit(0) end.not_to exceed_query_limit(0)
end end
end end
describe '.allowed_user?' do describe '.enabled?' do
let(:user) { create(:user) } let(:user) { create(:user) }
before do before do
stub_performance_bar_setting(allowed_group: 'my-group') stub_application_setting(performance_bar_allowed_group_id: -1)
end
it 'returns false when given user is nil' do
expect(described_class.enabled?(nil)).to be_falsy
end end
context 'when allowed group does not exist' do it 'returns false when allowed_group_id is nil' do
expect(described_class).to receive(:allowed_group_id).and_return(nil)
expect(described_class.enabled?(user)).to be_falsy
end
context 'when allowed group ID does not exist' do
it 'returns false' do it 'returns false' do
expect(described_class.allowed_user?(user)).to be_falsy expect(described_class.enabled?(user)).to be_falsy
end end
end end
context 'when allowed group exists' do context 'when allowed group exists' do
let!(:my_group) { create(:group, path: 'my-group') } let!(:my_group) { create(:group, path: 'my-group') }
before do
stub_application_setting(performance_bar_allowed_group_id: my_group.id)
end
context 'when user is not a member of the allowed group' do context 'when user is not a member of the allowed group' do
it 'returns false' do it 'returns false' do
expect(described_class.allowed_user?(user)).to be_falsy expect(described_class.enabled?(user)).to be_falsy
end end
it_behaves_like 'allowed user IDs are cached in Redis for 10 minutes' it_behaves_like 'allowed user IDs are cached'
end end
context 'when user is a member of the allowed group' do context 'when user is a member of the allowed group' do
...@@ -68,10 +58,10 @@ describe Gitlab::PerformanceBar do ...@@ -68,10 +58,10 @@ describe Gitlab::PerformanceBar do
end end
it 'returns true' do it 'returns true' do
expect(described_class.allowed_user?(user)).to be_truthy expect(described_class.enabled?(user)).to be_truthy
end end
it_behaves_like 'allowed user IDs are cached in Redis for 10 minutes' it_behaves_like 'allowed user IDs are cached'
end end
end end
...@@ -81,11 +71,11 @@ describe Gitlab::PerformanceBar do ...@@ -81,11 +71,11 @@ describe Gitlab::PerformanceBar do
before do before do
create(:group, path: 'my-group') create(:group, path: 'my-group')
nested_my_group.add_developer(user) nested_my_group.add_developer(user)
stub_performance_bar_setting(allowed_group: 'my-org/my-group') stub_application_setting(performance_bar_allowed_group_id: nested_my_group.id)
end end
it 'returns the nested group' do it 'returns the nested group' do
expect(described_class.allowed_user?(user)).to be_truthy expect(described_class.enabled?(user)).to be_truthy
end end
end end
...@@ -95,7 +85,7 @@ describe Gitlab::PerformanceBar do ...@@ -95,7 +85,7 @@ describe Gitlab::PerformanceBar do
end end
it 'returns false' do it 'returns false' do
expect(described_class.allowed_user?(user)).to be_falsy expect(described_class.enabled?(user)).to be_falsy
end end
end end
end end
......
...@@ -215,20 +215,27 @@ describe ApplicationSetting, models: true do ...@@ -215,20 +215,27 @@ describe ApplicationSetting, models: true do
end end
describe 'performance bar settings' do describe 'performance bar settings' do
before do describe 'performance_bar_allowed_group_id=' do
Flipper.unregister_groups context 'with a blank path' do
Flipper.register(:performance_team) before do
end setting.performance_bar_allowed_group_id = create(:group).full_path
end
after do it 'persists nil for a "" path and clears allowed user IDs cache' do
Flipper.unregister_groups expect(Gitlab::PerformanceBar).to receive(:expire_allowed_user_ids_cache)
end
describe 'performance_bar_allowed_group_id=' do setting.performance_bar_allowed_group_id = ''
it 'does not persist an invalid group path' do
setting.performance_bar_allowed_group_id = 'foo' expect(setting.performance_bar_allowed_group_id).to be_nil
end
end
context 'with an invalid path' do
it 'does not persist an invalid group path' do
setting.performance_bar_allowed_group_id = 'foo'
expect(setting.performance_bar_allowed_group_id).to be_nil expect(setting.performance_bar_allowed_group_id).to be_nil
end
end end
context 'with a path to an existing group' do context 'with a path to an existing group' do
...@@ -243,14 +250,28 @@ describe ApplicationSetting, models: true do ...@@ -243,14 +250,28 @@ describe ApplicationSetting, models: true do
end end
context 'when the given path is the same' do context 'when the given path is the same' do
before do context 'with a blank path' do
setting.performance_bar_allowed_group_id = group.full_path before do
setting.performance_bar_allowed_group_id = nil
end
it 'clears the cached allowed user IDs' do
expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
setting.performance_bar_allowed_group_id = ''
end
end end
it 'clears the cached allowed user IDs' do context 'with a valid path' do
expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache) before do
setting.performance_bar_allowed_group_id = group.full_path
end
it 'clears the cached allowed user IDs' do
expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
setting.performance_bar_allowed_group_id = group.full_path setting.performance_bar_allowed_group_id = group.full_path
end
end end
end end
end end
...@@ -276,83 +297,71 @@ describe ApplicationSetting, models: true do ...@@ -276,83 +297,71 @@ describe ApplicationSetting, models: true do
end end
end end
describe 'performance_bar_enabled?' do describe 'performance_bar_enabled' do
context 'with the Performance Bar is enabled globally' do context 'with the Performance Bar is enabled' do
before do let(:group) { create(:group) }
Feature.enable(:performance_bar)
end
it 'returns true' do
expect(setting).to be_performance_bar_enabled
end
end
context 'with the Performance Bar is enabled for the performance_team group' do
before do before do
Feature.enable_group(:performance_bar, :performance_team) setting.performance_bar_allowed_group_id = group.full_path
end end
it 'returns true' do it 'returns true' do
expect(setting).to be_performance_bar_enabled expect(setting.performance_bar_enabled).to be_truthy
end
end
context 'with the Performance Bar is enabled for a specific user' do
before do
Feature.enable(:performance_team, create(:user))
end
it 'returns false' do
expect(setting).not_to be_performance_bar_enabled
end end
end end
end end
describe 'performance_bar_enabled=' do describe 'performance_bar_enabled=' do
context 'when the performance bar is enabled' do context 'when the performance bar is enabled' do
let(:group) { create(:group) }
before do before do
Feature.enable(:performance_bar) setting.performance_bar_allowed_group_id = group.full_path
end end
context 'when passing true' do context 'when passing true' do
it 'does not clear allowed user IDs cache' do it 'does not clear allowed user IDs cache' do
expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache) expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
setting.performance_bar_enabled = true setting.performance_bar_enabled = true
expect(setting).to be_performance_bar_enabled expect(setting.performance_bar_allowed_group_id).to eq(group.id)
expect(setting.performance_bar_enabled).to be_truthy
end end
end end
context 'when passing false' do context 'when passing false' do
it 'disables the performance bar and clears allowed user IDs cache' do it 'disables the performance bar and clears allowed user IDs cache' do
expect(Gitlab::PerformanceBar).to receive(:expire_allowed_user_ids_cache) expect(Gitlab::PerformanceBar).to receive(:expire_allowed_user_ids_cache)
setting.performance_bar_enabled = false setting.performance_bar_enabled = false
expect(setting).not_to be_performance_bar_enabled expect(setting.performance_bar_allowed_group_id).to be_nil
expect(setting.performance_bar_enabled).to be_falsey
end end
end end
end end
context 'when the performance bar is disabled' do context 'when the performance bar is disabled' do
before do
Feature.disable(:performance_bar)
end
context 'when passing true' do context 'when passing true' do
it 'enables the performance bar and clears allowed user IDs cache' do it 'does nothing and does not clear allowed user IDs cache' do
expect(Gitlab::PerformanceBar).to receive(:expire_allowed_user_ids_cache) expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
setting.performance_bar_enabled = true setting.performance_bar_enabled = true
expect(setting).to be_performance_bar_enabled expect(setting.performance_bar_allowed_group_id).to be_nil
expect(setting.performance_bar_enabled).to be_falsey
end end
end end
context 'when passing false' do context 'when passing false' do
it 'does not clear allowed user IDs cache' do it 'does nothing and does not clear allowed user IDs cache' do
expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache) expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
setting.performance_bar_enabled = false setting.performance_bar_enabled = false
expect(setting).not_to be_performance_bar_enabled expect(setting.performance_bar_allowed_group_id).to be_nil
expect(setting.performance_bar_enabled).to be_falsey
end end
end end
end end
......
...@@ -29,10 +29,6 @@ module StubConfiguration ...@@ -29,10 +29,6 @@ module StubConfiguration
allow(Gitlab.config.omniauth).to receive_messages(messages) allow(Gitlab.config.omniauth).to receive_messages(messages)
end end
def stub_performance_bar_setting(messages)
allow(Gitlab.config.performance_bar).to receive_messages(messages)
end
private private
# Modifies stubbed messages to also stub possible predicate versions # Modifies stubbed messages to also stub possible predicate versions
......
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