Using Sentry, while useful, poses two problems you have to choose from: 1. All errors are reported separately, making it easy to create issues but also making it next to impossible to see other errors (due to the sheer volume of threshold errors). 2. Errors can be grouped or merged together, reducing the noise. This however also means it's (as far as I can tell) much harder to automatically create GitLab issues from Sentry for the offending controllers. Since both solutions are terrible I decided to go with a third option: not using Sentry for this at all. Instead we'll investigate using Prometheus alerts and Grafana dashboards for this, which has the added benefit of being able to more accurately measure the behaviour over time. Note that throwing errors in test environments is still enabled, and whitelisting is still necessary to prevent that from happening (and that in turn still requires that developers create issues).
2.1 KiB
Query Count Limits
Each controller or API endpoint is allowed to execute up to 100 SQL queries and in test environments we'll raise an error when this threshold is exceeded.
Solving Failing Tests
When a test fails because it executes more than 100 SQL queries there are two solutions to this problem:
- Reduce the number of SQL queries that are executed.
- Whitelist the controller or API endpoint.
You should only resort to whitelisting when an existing controller or endpoint is to blame as in this case reducing the number of SQL queries can take a lot of effort. Newly added controllers and endpoints are not allowed to execute more than 100 SQL queries and no exceptions will be made for this rule. If a large number of SQL queries is necessary to perform certain work it's best to have this work performed by Sidekiq instead of doing this directly in a web request.
Whitelisting
In the event that you have to whitelist a controller you'll first need to
create an issue. This issue should (preferably in the title) mention the
controller or endpoint and include the appropriate labels (database
,
performance
, and at least a team specific label such as Discussion
).
Once the issue has been created you can whitelist the code in question. For
Rails controllers it's best to create a before_action
hook that runs as early
as possible. The called method in turn should call
Gitlab::QueryLimiting.whitelist('issue URL here')
. For example:
class MyController < ApplicationController
before_action :whitelist_query_limiting, only: [:show]
def index
# ...
end
def show
# ...
end
def whitelist_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/...')
end
end
By using a before_action
you don't have to modify the controller method in
question, reducing the likelihood of merge conflicts.
For Grape API endpoints there unfortunately is not a reliable way of running a hook before a specific endpoint. This means that you have to add the whitelist call directly into the endpoint like so:
get '/projects/:id/foo' do
Gitlab::QueryLimiting.whitelist('...')
# ...
end