Commit c0bc30f1 authored by Bob Van Landuyt's avatar Bob Van Landuyt Committed by Marcia Ramos

Add documentation on feature categorization

This adds developer-documentation on how to categorize controller
actions.

The documentation on categorizing Sidekiq workers has been moved into
the same place and linked from the the styleguide.
parent 18645920
......@@ -101,6 +101,7 @@ Complementary reads:
- [Windows Development on GCP](windows.md)
- [Code Intelligence](code_intelligence/index.md)
- [Approval Rules](approval_rules.md)
- [Feature categorization](feature_categorization/index.md)
## Performance guides
......
# Feature Categorization
> [Introduced](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/269) in GitLab 13.2.
Each Sidekiq worker, controller action, or (eventually) API endpoint
must declare a `feature_category` attribute. This attribute maps each
of these to a [feature
category](https://about.gitlab.com/handbook/product/product-categories/). This
is done for error budgeting, alert routing, and team attribution.
The list of feature categories can be found in the file `config/feature_categories.yml`.
This file is generated from the
[`stages.yml`](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml)
data file used in the GitLab Handbook and other GitLab resources.
## Updating `config/feature_categories.yml`
Occasionally new features will be added to GitLab stages, groups, and
product categories. When this occurs, you can automatically update
`config/feature_categories.yml` by running
`scripts/update-feature-categories`. This script will fetch and parse
[`stages.yml`](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml)
and generate a new version of the file, which needs to be committed to
the repository.
The [Scalabilitity
team](https://about.gitlab.com/handbook/engineering/infrastructure/team/scalability)
currently maintains the `stages.yml` file. They will automatically be
notified on Slack when the file becomes outdated.
## Sidekiq workers
The declaration uses the `feature_category` class method, as shown below.
```ruby
class SomeScheduledTaskWorker
include ApplicationWorker
# Declares that this worker is part of the
# `continuous_integration` feature category
feature_category :continuous_integration
# ...
end
```
The feature categories specified using `feature_category` should be
defined in
[`config/feature_categories.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/feature_categories.yml). If
not, the specs will fail.
### Excluding Sidekiq workers from feature categorization
A few Sidekiq workers, that are used across all features, cannot be mapped to a
single category. These should be declared as such using the `feature_category_not_owned!`
declaration, as shown below:
```ruby
class SomeCrossCuttingConcernWorker
include ApplicationWorker
# Declares that this worker does not map to a feature category
feature_category_not_owned!
# ...
end
```
## Rails controllers
Specifying feature categories on controller actions can be done using
the `feature_category` class method.
A feature category can be specified on an entire controller
using:
```ruby
class Projects::MergeRequestsController < ApplicationController
feature_category :source_code_management
end
```
The feature category can be limited to a list of actions using the
`only` argument, actions can be excluded using the `except` argument.
```ruby
class Projects::MergeRequestsController < ApplicationController
feature_category :code_testing, only: [:metrics_reports]
feature_category :source_code_management, except: [:test_reports, :coverage_reports]
end
```
`except` and `only` arguments can not be combined.
When specifying `except` all other actions will get the specified
category assigned.
The assignment can also be scoped using `if` and `unless` procs:
```ruby
class Projects::MergeRequestsController < ApplicationController
feature_category :source_code_management,
unless: -> (action) { action.include?("reports") }
if: -> (action) { action.include?("widget") }
end
```
In this case, both procs need to be satisfied for the action to get
the category assigned.
### Excluding controller actions from feature categorization
In the rare case an action cannot be tied to a feature category this
can be done using the `not_owned` feature category.
```ruby
class Admin::LogsController < ApplicationController
feature_category :not_owned
end
```
### Ensuring feature categories are valid
The `spec/controllers/every_controller_spec.rb` will iterate over all
defined routes, and check the controller to see if a category is
assigned to all actions.
The spec also validates if the used feature categories are known. And
if the actions used in `only` and `except` configuration still exist
as routes.
......@@ -378,55 +378,10 @@ We use the following approach to determine whether a worker is CPU-bound:
- Note that these values should not be used over small sample sizes, but
rather over fairly large aggregates.
## Feature Categorization
## Feature category
Each Sidekiq worker, or one of its ancestor classes, must declare a
`feature_category` attribute. This attribute maps each worker to a feature
category. This is done for error budgeting, alert routing, and team attribution
for Sidekiq workers.
The declaration uses the `feature_category` class method, as shown below.
```ruby
class SomeScheduledTaskWorker
include ApplicationWorker
# Declares that this worker is part of the
# `continuous_integration` feature category
feature_category :continuous_integration
# ...
end
```
The list of value values can be found in the file `config/feature_categories.yml`.
This file is, in turn generated from the [`stages.yml` from the GitLab Company Handbook
source](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml).
### Updating `config/feature_categories.yml`
Occasionally new features will be added to GitLab stages. When this occurs, you
can automatically update `config/feature_categories.yml` by running
`scripts/update-feature-categories`. This script will fetch and parse
[`stages.yml`](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml)
and generate a new version of the file, which needs to be checked into source control.
### Excluding Sidekiq workers from feature categorization
A few Sidekiq workers, that are used across all features, cannot be mapped to a
single category. These should be declared as such using the `feature_category_not_owned!`
declaration, as shown below:
```ruby
class SomeCrossCuttingConcernWorker
include ApplicationWorker
# Declares that this worker does not map to a feature category
feature_category_not_owned!
# ...
end
```
All Sidekiq workers must define a known [feature
category](feature_categorization/index.md#sidekiq-workers).
## Job weights
......
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