Skip to content

Remove subject to prevent nested calls to reentrant_mutex in Ruby 3.0

Roy Zwambag requested to merge 379686-fix-enumerator_next_patch_spec-ruby3 into master

What does this MR do and why?

With the upgrade of rspec-support to v3.10.3, Mutex#owned? is used to allow RSpec::Support::ReentrantMutex to work in nested Fibers on Ruby 3.0 and later. However, this causes a spec to hang forever (causing timeouts in the Ruby 3 pipeline) and other specs to fail in Ruby 3 with the error ThreadError: Attempt to unlock a mutex which is locked by another thread/fiber.

It tries to call @mutex.lock while the Mutex is already locked. This issue is similar to https://github.com/rspec/rspec-support/issues/552. If we don't call subject, but directly call the value of what we set subject to it will not have this issue.

This change seems unrelated to EnumeratorNextPatch and the spec itself, but rather to Enumerator. It is reproducible with this small code example as well:

# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Yield stuck' do
  subject { enumerator.next }

  let(:yield_value) { 1 }
  let(:enumerator) { Enumerator.new { |yielder| yielder << yield_value } }

  it 'equals 1' do
    expect(subject).to eq 1
  end
end

How to set up and validate locally

Run this spec in both Ruby 3 and Ruby 2.7, it should still pass in Ruby 2.7 and should not break in Ruby 3 anymore.

Ruby 3.0 pipeline: https://gitlab.com/gitlab-org/gitlab/-/pipelines/682457644#/

Ruby 2.7 pipeline: https://gitlab.com/gitlab-org/gitlab/-/pipelines/682458296#/

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #379686 (closed)

Edited by Roy Zwambag

Merge request reports