Fix infinite retry on detected language rename

What does this MR do and why?

When Gitaly returns a new canonical name for a language whose language_id already exists under a different ProgrammingLanguage name, repository language detection repeatedly fails on the unique language_id constraint and retries forever. This can stall Sidekiq and, as reported, take instances down.

This MR:

  • Resolves detected languages by language_id first, then by name.
  • Updates existing records with the detected canonical name and language_id when it is safe.
  • Returns the language_id match unchanged when the detected name is already taken by another record (no data repair).
  • Matches resolved languages by language_id first when building repository language insertions.
  • Recovers from ActiveRecord::RecordNotUnique by finding the conflicting record instead of retrying indefinitely.

This is the main fix, stacked on top of two refactoring MRs:

References

#602294 (closed)

How to set up and validate locally

  1. Check out this branch (stacked on the resolver extraction branch):

    git switch 602294-fix-language-rename-infinite-retry
  2. Run affected specs:

    bin/rspec spec/lib/gitlab/language_detection_spec.rb spec/lib/gitlab/language_detection/programming_language_resolver_spec.rb spec/services/projects/detect_repository_languages_service_spec.rb
  3. Run RuboCop:

    bundle exec rubocop lib/gitlab/language_detection.rb lib/gitlab/language_detection/programming_language_resolver.rb spec/lib/gitlab/language_detection_spec.rb spec/lib/gitlab/language_detection/programming_language_resolver_spec.rb

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.

Edited by Vasilii Iakliushin

Merge request reports

Loading