Skip to content

Draft: Adds Gitlab::Configuration for managing settings

John Mason requested to merge jm-better-settings into master

What does this MR do and why?

Adds Gitlab::Configuration which is an alternative to ApplicationSetting. A "Configuration" is modeled to be a collection of settings, loosely related to different "sections" of application settings. It uses Single Table Inheritance, so adding different settings does not require any DB migrations. The only thing required is to create a class that inherits from Gitlab::Configuration and add the appropriate json schema. What's cool about inheritance is different configuration classes of settings can have their own custom methods or validation logic.

This MR introduces Gitlab::Config::Search::CurationSettings as a proof of concept.

  • Goal of this MR: quickly add DB configurable settings for search index curation in order to have different thresholds between staging and production
  • Follow up of this MR: Dogfood for a while as a proof of concept and extend/publicize to other teams by migrating other search settings away from ApplicationSetting table and adding to developer documentation
  • Non Goal of this MR: Publicize this as a ready-to-go, battle tested alternative to ApplicationSetting

How to add new settings

Creating a new class

To create a new configuration of settings, at the very minimum, your class needs to look something like this:

class EnterpriseSettings < Gitlab::Configuration
  self.default_settings = {
    shields: { value: 50.0, description: 'Percentage of total power to direct towards defending electromagnetic radiation' }
  }
end

Then in a console:

[1] pry(main)> EnterpriseSettings.instance
=> #<EnterpriseSettings:0x0000000123f65b98
 id: 4,
 class_name: "EnterpriseSettings",
 settings: {"shields"=>{"value"=>50.0, "description"=>"Percentage of total power to direct towards defending electromagnetic radiation"}},
 created_at: Thu, 12 Jan 2023 01:24:18.451500000 UTC +00:00,
 updated_at: Thu, 12 Jan 2023 01:24:18.451500000 UTC +00:00>

[2] pry(main)> EnterpriseSettings.shields
=> 50.0

Adding new settings to a class

To add new settings, just append to default_settings

 class EnterpriseSettings < Gitlab::Configuration
   self.default_settings = {
-    shields: { value: 50.0, description: 'Percentage of total power to direct towards defending electromagnetic radiation' }
+    shields: { value: 50.0, description: 'Percentage of total power to direct towards defending electromagnetic radiation' },
+    warp: { value: false, description: 'Toggle warp drive' }
   }
 end

The singleton instance will be updated when cache expires (defaults to 60 seconds). Any keys from pre-existing settings will not be affected, even if the values of those keys in default_settings are changed.

[1] pry(main)> EnterpriseSettings.instance
=> #<EnterpriseSettings:0x000000013763c0a8
 id: 4,
 class_name: "EnterpriseSettings",
 settings:
  {"shields"=>{"value"=>50.0, "description"=>"[FILTERED]"}, "warp"=>{"value"=>false, "description"=>"[FILTERED]"}},
 created_at: Thu, 12 Jan 2023 01:24:18.451500000 UTC +00:00,
 updated_at: Thu, 12 Jan 2023 01:33:47.508223000 UTC +00:00>
[2] pry(main)> EnterpriseSettings.warp
=> false
[3] pry(main)> EnterpriseSettings.warp = true
=> true

Removing settings to a class

Removing settings is not supported yet.

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by John Mason

Merge request reports