From: daniel@...42.com Date: 2020-12-02T14:00:52+00:00 Subject: [ruby-core:101202] [Ruby master Bug#17359] Ractor copy mode is not Ractor-safe Issue #17359 has been updated by Dan0042 (Daniel DeLorme). ko1 (Koichi Sasada) wrote in #note-6: > One idea is prohibit `initialize_copy` written in Ruby, for ractor_copy. > But I'm not sure how it is feasible. > > ``` > ko1@aluminium:~$ gem-codesearch 'def initialize_clone' | wc -l > 120 > ko1@aluminium:~$ gem-codesearch 'def initialize_copy' | wc -l > 3430 > ``` I think it's feasible. `initialize_clone` and `initialize_copy` are mostly (only?) used because `clone` and `dup` only perform shallow copies. See the examples below. Since ractor-copy already performs a deep-copy, the extra copy/cloning in these examples is redundant. Actually... it's buggy? Since the `initialize_clone` is executed in the parent ractor, the objects are created as part of the parent ractor's heap rather than the child ractor's heap? ``` activemodel-6.0.0/lib/active_model/attribute_set.rb 72: def initialize_clone(_) 73- @attributes = attributes.clone 74- super 75- end regexp_parser-1.6.0/lib/regexp_parser/expression/classes/group.rb 36: def initialize_clone(orig) 37- @name = orig.name.dup 38- super 39- end 40- end regexp_parser-1.6.0/lib/regexp_parser/expression/quantifier.rb 15: def initialize_clone(orig) 16- @text = orig.text.dup 17- super 18- end regexp_parser-1.6.0/lib/regexp_parser/expression/subexpression.rb 15: def initialize_clone(orig) 16- self.expressions = orig.expressions.map(&:clone) 17- super 18- end regexp_parser-1.6.0/lib/regexp_parser/expression.rb 24: def initialize_clone(orig) 25- self.text = (orig.text ? orig.text.dup : nil) 26- self.options = (orig.options ? orig.options.dup : nil) 27- self.quantifier = (orig.quantifier ? orig.quantifier.clone : nil) 28- super 29- end actionpack-6.0.0/lib/action_controller/metal/strong_parameters.rb 1017: def initialize_copy(source) 1018- super 1019- @parameters = @parameters.dup 1020- end actionpack-6.0.0/lib/action_dispatch/http/content_security_policy.rb 157: def initialize_copy(other) 158- @directives = other.directives.deep_dup 159- end actionpack-6.0.0/lib/action_dispatch/middleware/flash.rb 147: def initialize_copy(other) 148- if other.now_is_loaded? 149- @now = other.now.dup 150- @now.flash = self 151- end 152- super 153- end actionpack-6.0.0/lib/action_dispatch/middleware/stack.rb 95: def initialize_copy(other) 96- self.middlewares = other.middlewares.dup 97- end actionview-6.0.0/lib/action_view/path_set.rb 22: def initialize_copy(other) 23- @paths = other.paths.dup 24- self 25- end ``` ---------------------------------------- Bug #17359: Ractor copy mode is not Ractor-safe https://bugs.ruby-lang.org/issues/17359#change-88886 * Author: marcandre (Marc-Andre Lafortune) * Status: Open * Priority: Normal * Assignee: ko1 (Koichi Sasada) * ruby -v: ruby 3.0.0dev (2020-11-30T10:06:25Z master 89774a938a) [x86_64-darwin18] * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN ---------------------------------------- It should not be possible to mutate an object across Ractors, but the copy mode allows it currently: ```ruby class Foo attr_accessor :x def initialize_copy(*) $last = self super end end o = Foo.new o.x = 42 r = Ractor.new(o) do |copy| puts copy.x # => 42 Ractor.yield :sync Ractor.yield :sync puts copy.x # => 666 end r.take # => :sync $last.x = 666 r.take # => :sync r.take ``` Maybe the `copy` object should be marked as moved? -- https://bugs.ruby-lang.org/ Unsubscribe: