Add labkit rate limit adapter for cohort 3 keys
What does this MR do and why?
Migrates Gitlab::ApplicationRateLimiter keys whose call graph contains .peek callers to Labkit::RateLimit::Limiter (cohort 3 of the staged migration tracked under epic gitlab-com/gl-infra&2021).
This is the first cohort that includes peek (read-without-increment) callers. Peek needed Limiter#peek upstream in labkit-ruby, which landed in v1.19.0; this MR bumps gitlab-labkit ~> 1.17.0 to ~> 1.19.0.
Adapter and dispatch changes
- Adds
Gitlab::ApplicationRateLimiter::LabkitAdapter.run_peek!companion torun!, callinglimiter.peek(no INCR, no TTL extension). - Lifts the
!peekguard inGitlab::ApplicationRateLimiter._throttled?so peek dispatches now route through the adapter as well. - Refactors
_throttled?for readability: extractsdispatch_to_labkitandlegacy_throttled?private helpers so the orchestrator stays below the cyclomatic-complexity ceiling.
Cohort 3 registration
| Key | CE/EE | Characteristics |
|---|---|---|
glql |
CE | [query_sha] |
permanent_email_failure |
CE | [email] |
temporary_email_failure |
CE | [email] |
update_namespace_name |
CE | [namespace] |
hard_phone_verification_transactions_limit |
EE | [scope] |
soft_phone_verification_transactions_limit |
EE | [scope] |
All six tagged flag_scope: :cohort_3 in SupportedRateLimits.
web_hook_calls{,_low,_mid} is deliberately excluded: every caller passes a threshold: override that the adapter cannot honor, so it would always route to legacy via record_override. Registering it would never exercise the labkit path.
Mapping the 10 production peek call sites to keys
| Key | Peek call sites |
|---|---|
glql |
app/services/analytics/glql/query_service.rb:115 |
permanent_email_failure |
app/models/notification_recipient.rb:116 |
temporary_email_failure |
app/models/notification_recipient.rb:117 |
update_namespace_name |
ee/app/models/ee/namespace.rb:1090 |
hard_phone_verification_transactions_limit |
ee/app/models/concerns/identity_verifiable.rb:180,202; ee/app/helpers/arkose_helper.rb:7 |
soft_phone_verification_transactions_limit |
ee/app/models/concerns/identity_verifiable.rb:207; ee/lib/identity_verification/user_risk_profile.rb:80 |
(excluded) web_hook_calls{,_low,_mid} |
lib/gitlab/web_hooks/rate_limiter.rb:36 (always passes threshold: override) |
Feature flags
Two cohort-wide WIP ops flags, both default off:
rate_limiter_use_labkit_cohort_3— enable shadow pathrate_limiter_use_labkit_cohort_3_enforce— switch authoritative decision to labkit
Operate as fully on or fully off; the adapter uses Feature.current_request as the actor, which resolves to a per-call UUID for non-request callers, making percentage rollouts non-deterministic.
References
- Cohort 3 issue: gitlab-com/gl-infra/production-engineering#28810
- Parent migration tracker: gitlab-com/gl-infra/production-engineering#28808
- Parent epic: gitlab-com/gl-infra&2021
- Prior cohort MRs: !233816 (merged) (cohort 1), !234565 (merged) (cohort 2)
- Rollout plan with Grafana go/no-go queries: gitlab-com/gl-infra/production-engineering#28810 (note 3328172110)
- Local smoke-test plan + driver script + results: gitlab-com/gl-infra/production-engineering#28810 (note 3328342914)
How to set up and validate locally
-
bundle installto pick upgitlab-labkit 1.19.0. -
Verify the gem bump and cohort 3 registration:
bin/rails runner 'puts Gem.loaded_specs["gitlab-labkit"].version' # expected: 1.19.0 bin/rails runner ' puts Gitlab::ApplicationRateLimiter::LabkitAdapter::SupportedRateLimits.all .select { |_, spec| spec[:flag_scope] == :cohort_3 } .keys.sort ' # expected (EE): glql, hard_phone_verification_transactions_limit, # permanent_email_failure, soft_phone_verification_transactions_limit, # temporary_email_failure, update_namespace_name -
Run the smoke-test driver from the smoke-test comment (save as
/tmp/cohort3_smoke.rb):bin/rails runner /tmp/cohort3_smoke.rbExercises shadow + enforce paths, override fallback, EE Symbol-scope serialization, and cleans up after itself. All seven cases were PASS against my GDK.
-
Run the affected spec files:
bundle exec rspec \ spec/lib/gitlab/application_rate_limiter_spec.rb \ spec/lib/gitlab/application_rate_limiter/labkit_adapter_spec.rb \ ee/spec/lib/ee/gitlab/application_rate_limiter_spec.rb \ ee/spec/lib/ee/gitlab/application_rate_limiter/labkit_adapter/supported_rate_limits_spec.rbExpected: 120 examples, 0 failures.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist.
- Specs added for
dispatch_to_labkit,run_peek!, peek dispatch in_throttled?, cohort 3 flag-basis resolution, and EE phone-verification cohort 3 registration. - All four affected spec files pass locally (120/120).
- RuboCop clean on changed files.
-
bundle exec rake bundler:gemfile:syncrun (Gemfile.next.lock kept in sync with Gemfile.lock). - Smoke-tested end-to-end against local GDK Redis (driver script in the cohort 3 issue).
- Rollout plan with Grafana go/no-go queries posted on the cohort 3 issue.
-
introduced_by_urlpopulated in both feature flag YAMLs (will fill in once this MR has a number). -
rollout_issue_urlpopulated in both feature flag YAMLs (pending rollout-steps issue).