You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I cannot figure out why the spec in the 2nd context does not terminate:
RSpec.describe Spec do
context 'terminates' do
let(:s) { Sync { 1 } }
it 'eq' do
expect(s).to eq 1
end
end
context 'does not terminate' do
let(:s) { Sync { param } }
let(:param) { 1 }
it 'eq' do
expect(s).to eq 1
end
end
end
Using ruby 3.1.2 and async 2.0.2.
The text was updated successfully, but these errors were encountered:
IIRC, this is because let blocks are "thread safe" and have an implicit shared mutex around every request. It's supposed to be reentrant but because Sync { param } happens on a different fiber, it's effectively a deadlock, i.e. it's not that different from:
To resolve s it locks the mutex for the current (main) thread. Then it creates a new thread (Sync block creates a new fiber) and then tries to lock the mutex again and this deadlocks.
The real issue here is whether RSpec should be "thread safe" in this way. I personally think it's wrong.
I got pretty frustrated with RSpec for this reason as well as others, and implemented https://github.com/ioquatix/sus which explicitly avoids this problem. I don't have a good answer and can't fix RSpec, maybe they will avoid having a mutex around their let variables.
I cannot figure out why the spec in the 2nd context does not terminate:
Using ruby 3.1.2 and async 2.0.2.
The text was updated successfully, but these errors were encountered: