Avoid mutating cached noteable in Note#touch_noteable
What does this MR do?
Note#touch_noteable ends with noteable_object&.touch, which mutates the in-memory Issue/MergeRequest/etc. ActiveRecord instance. When that record is held via a let_it_be cache and frozen, the touch raises FrozenError.
This MR detects the frozen case and uses touch_all on a single-record relation so the SQL UPDATE is issued without mutating the cached AR instance:
return unless noteable_object
if noteable_object.frozen?
# `noteable_object` may be a `let_it_be`-cached frozen instance in tests;
# under freeze: true that would raise FrozenError. Use `touch_all` so the
# UPDATE goes out without mutating the cached AR object.
noteable_object.class.where(id: noteable_object.id).touch_all
else
noteable_object.touch
endSame SQL, same effect on the database; just no in-memory side effect on a cached object that happens to be frozen.
Why?
This is the highest-volume mutation site surfaced by the freeze-flip probe (#600433 (closed)): 3,168 occurrences of FrozenError originated from app/models/note.rb:596. It propagates because every test that creates a Note triggers a .touch on its noteable (Issue, MR, Epic, etc.), and let_it_be(:issue) / let_it_be(:merge_request) etc. are extremely common.
Empirically validated: the validation MR (!236528 (closed)) layered this fix together with two others on top of the probe (!236505 (closed)), and the probe pipeline's failure count dropped from 665 → 183 (a 72.5% reduction), with zero remaining occurrences of note.rb:596 in the validation traces.
Verification
- Local:
bundle exec rspec spec/models/note_spec.rb - This MR's CI run.
- Validation evidence: !236528 (closed) (compare https://gitlab.com/gitlab-org/gitlab/-/pipelines/2533568410 baseline vs https://gitlab.com/gitlab-org/gitlab/-/pipelines/2534042883 with this fix layered).
References
- #600433 (closed) (production-code mutation tracking issue)
- #600267 (closed) (let_it_be freeze rollout)
- !236505 (closed) (probe MR)
- !236528 (closed) (validation MR)
A sibling MR (!236544 (merged) for base_label.rb) and another forthcoming for ee/app/models/ee/note.rb complete the top-3 fixes.
/cc @pedropombeiro