
Issue #21309 has been updated by Eregon (Benoit Daloze).
Now, more generally, if we got some shareable mutable state, then we'd need a shareable mutex. I just haven't yet encountered that case.
Yes, and the shareable mutable state can't be accessed by Ractor, as Ractor prevents shareable mutable state entirely. So making the Mutex shareable in most situations would likely mean it just fails a little bit later, in a way that isn't really solvable. So I don't think it would help much if at all, but it would be interesting to see if there are examples where it would actually solve something. For example on the Faraday case it would fail on `@default_options =` (on the `Faraday::Middleware` class). For Timeout there is another semantics mismatch: if you use Ractors you shouldn't use Threads, otherwise you lose most benefits of using an actor model. So basically if you use Ractor you shouldn't use `Timeout`, even if Timeout wouldn't raise `Ractor::IsolationError`s. IOW, my impression is people try to use Ractor because they want parallelism and they don't care about the actor model and want to keep using threads (or gems that need threads). That seems a bad match full of clashes.
there's still some significant difference that may make it harder.
I think it's actually easier, though of course a lot of work. CPython has reference counting, which is hell for concurrency (in terms of overhead at least). CRuby has a rather normal GC, there are tons of existing concurrent GCs which could be adapted, nothing new there (though still a lot of work). Array/Hash/Set/etc would need to have synchronization, that I would imagine we can use the same approach as CPython or another, there are many solutions. ---------------------------------------- Feature #21309: Can Thread::Mutex be Ractor shareable? https://bugs.ruby-lang.org/issues/21309#change-112913 * Author: osyoyu (Daisuke Aritomo) * Status: Open ---------------------------------------- ## Background Keeping a `Mutex` object in a constant or a class instance variable is a common pattern seen in code with thread safety in mind. However, this kind of code does not play well with Ractors: ```ruby require 'thread' class C MUTEX = Mutex.new def self.foo MUTEX.synchronize { p 1 } end end Ractor.new { C.foo }.take ``` ``` t.rb:11: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<Thread:0x000000011d80f368 run> terminated with exception (report_on_exception is true): t.rb:7:in 'C.foo': can not access non-shareable objects in constant C::MUTEX by non-main ractor. (Ractor::IsolationError) from t.rb:12:in 'block in <main>' <internal:ractor>:711:in 'Ractor#take': thrown by remote Ractor. (Ractor::RemoteError) from t.rb:13:in '<main>' t.rb:7:in 'C.foo': can not access non-shareable objects in constant C::MUTEX by non-main ractor. (Ractor::IsolationError) from t.rb:12:in 'block in <main>' ``` Many libraries follow this pattern. `Mutex` not being Ractor shareable is blocking these libraries from being used from inside Ractors. `Timeout` in stdlib in particular has large impact since it is required from many other gems by default, including `net/http`. https://github.com/ruby/timeout/blob/v0.4.3/lib/timeout.rb#L49-L50 https://github.com/lostisland/faraday/blob/v2.13.1/lib/faraday/middleware.rb... ## Proposal Make built-in concurrency primitives (Thread::Mutex, Thread::ConditionVariable and Thread::Queue) Ractor shareable. While this idea may not be strictly aligned with idea of the Ractor world (exchanging messages for controlling concurrency?), I have the feeling that too many code is blocked from running in Ractors because `Mutex` is not Ractor shareable. Allowing `Mutex`es to be shared would make a large portion of existing Ruby code Ractor-compatible, or at least make migration much easier. I believe that it won't be semantically incorrect, since they are concurrency primitives after all. One thing to consider that the current `Mutex` implementation is based on the GVL (I believe so). Migration to some other implementation e.g. pthread_mutex or CRITICAL_SECTION may be needed to make Mutex work well on Ractors. -- https://bugs.ruby-lang.org/