From: "osyoyu (Daisuke Aritomo) via ruby-core" Date: 2025-05-06T08:19:39+00:00 Subject: [ruby-core:121843] [Ruby Feature#21309] Can Thread::Mutex be Ractor shareable? Issue #21309 has been updated by osyoyu (Daisuke Aritomo). > At least for Queue it's not that simple, because it contains objects Indeed, you're right about Queue. I overlooked that. Since Queue isn't really a concurrency primitive, I think it'd be fine remaining Ractor unshareable. On the other hand, I still believe that Mutex and ConditionVariable should be Ractor-shareable. Of course it'd be a great boost if Timeout becomes Ractor compatible, but in my view there's no harm in making Mutex shareable as well. > My impression is yes it's (sometimes very) hard to make existing Ruby code Ractor-compatible, and it's due to the Ractor/actor programming model. I agree that there are fundamental constraints imposed by the actor model. At the same time, I think it's also true that existing code often can't run inside a Ractor simply because the necessary building blocks haven't been made Ractor compatible yet. ---------------------------------------- Feature #21309: Can Thread::Mutex be Ractor shareable? https://bugs.ruby-lang.org/issues/21309#change-112905 * 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. # 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
' :711:in 'Ractor#take': thrown by remote Ractor. (Ractor::RemoteError) from t.rb:13:in '
' 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
' ``` 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#L13 ## 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/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/