Skip to content

Strong memoize tag_names and branch_names in repository settings

What does this MR do and why?

Use strong_memoize for tag_names and branch_names in projects/settings/repository_controller#show.

This optimization reduces external dependencies and improves response times by keeping frequently accessed data available throughout the request lifecycle. This step will allow us to stop relying on the Redis cache to store tag_names and branch_names.

Steps to reproduce this locally

The following steps are dedicated to testing tag_names results. A similar process is needed to test branch_names.

Prerequisites

  • Local GitLab development environment (GDK)
  • A project with a significant number of tags (5000+ tags as mentioned in the review)

Step 1: Set up the test scenario

  1. Create or use a project with many tags:

       # In your test project, create multiple tags if needed
       for i in {1..5000}; do
        git tag "v1.0.$i"
       done
    
       git push --tags
  2. Create protected tags with wildcard patterns:

    • Navigate to your project's Settings → Repository → Protected tags
    • Add a protected tag with a wildcard pattern like v* or v1.0.* that matches many tags

Step 2: Reproduce the performance issue (Before the fix)

  1. Remove the Redis cache for tag_names (this simulates the planned removal):

    # In app/models/repository.rb, comment out or remove this line:
    # cache_method_as_redis_set :tag_names, fallback: []
  2. Test the repository settings page:

    • Navigate to /{namespace}/{project}/-/settings/repository
    • Observe the performance when loading the Protected tags section
    • Note: Without the cache and without this MR's fix, each protected tag would call @project.repository.tag_names repeatedly, causing performance degradation.
  3. Test the protected tag show page:

    • Click on a protected tag that matches many tags (e.g., "5000 matching tags")
    • Navigate to /{namespace}/{project}/-/protected_tags/{id}
    • Observe the performance and behavior

Step 3: Apply the MR changes and test the fix

  1. Apply this MR's changes or checkout the branch:

    git checkout jtapiab/555064-use-refsfinder-in-refmatcher-to-avoid-branches-and-tags-cache-core

  2. Test the repository settings page again:

    • Navigate to /{namespace}/{project}/-/settings/repository
    • The page should load faster because:
      • @tag_names is cached using Gitlab::SafeRequestStore (request-level cache)
      • Multiple protected tags reuse the same cached tag_names collection
      • No repeated calls to @project.repository.tag_names

Step 4: Verify the behavioral changes

  1. Repository Settings Page (define_protected_refs method):

    • Before: Each tag.matching(@project.repository.tag_names) call fetched tag names from repository.
    • After: All calls use cached @tag_names from Gitlab::SafeRequestStore.
  2. Template Changes:

    • Before: protected_tag.matching(repository.tag_names) in the view template
    • After: protected_tag.matching(@tag_names) using the cached instance variable

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #555064 (closed)

Edited by Javiera Tapia

Merge request reports

Loading