Move MergeRequestDiff keep_around_commits to after_create_commit

Summary

  • Moves keep_around Gitaly RPCs out of database transactions into async Sidekiq workers via after_commit callbacks
  • Applies to MergeRequestDiff, MergeRequest, Note, and DiffNote
  • Behind the async_keep_around_refs_for_merge_request_diffs feature flag with synchronous fallback when disabled
  • Introduces MergeRequests::KeepAroundRefsWorker and MergeRequests::KeepAroundRefsService to handle keep-around ref creation asynchronously

Relates to https://gitlab.com/gitlab-org/gitlab/-/issues/589480

Technical details

MergeRequestDiff#save_git_content is an after_create callback that runs inside the save!/create! transaction. At the end of this method, keep_around_commits calls repository.keep_around(start_commit_sha, head_commit_sha) — a Gitaly RPC that holds the database connection idle while waiting for the I/O response. Similar patterns exist in MergeRequest#keep_around_commit, Note#keep_around_commit, and DiffNote's keep_around_commits (via DiffPositionableNote).

This change:

  1. Adds after_commit callbacks (enqueue_keep_around_commit(s)) to MergeRequestDiff, MergeRequest, Note, and DiffNote that enqueue an async Sidekiq worker
  2. Guards the synchronous after_save keep-around calls with the feature flag so they become no-ops when enabled
  3. Preserves the merge_head? guard in MergeRequestDiff#enqueue_keep_around_commits — merge_head diffs are intentionally skipped since those temporary merge commits are kept alive via MergeRequest#merge_ref_path
  4. Worker has retry: 20 and is idempotent

Risk

Minimal. If keep_around_commits fails after commit, the SHAs may eventually be garbage collected, but they can be re-kept on the next diff creation. The operation is idempotent and has no data integrity dependency on the transaction.

Gitaly has a 10-day grace period (normal housekeeping) or 30-minute grace period (manual prune) before unreachable objects are pruned. The window between transaction commit and worker execution is milliseconds, and commits are typically reachable via MR refs anyway.

Edited by Marc Shaw

Merge request reports

Loading