Actions
Bug #19374
openIssue with Ractor.make_shareable with curried procs
Description
This works, but shouldn't:
class Worker
def start(&blk)
blk = blk.curry # bug in ruby allows sharing of non-shareable proc
Ractor.make_shareable(blk)
@ractor = Ractor.new(blk) do |b|
main = b.call
p "from ractor: #{main}"
end
end
def work
@ractor.take
end
end
worker = Worker.new
a = self # unshareable main object
p "from main: #{a}"
worker.start { a }
worker.work
The curried proc has a reference to the original proc and it's not checked for shareability.
Updated by luke-gru (Luke Gruber) almost 2 years ago
This issue is fixed by https://github.com/ruby/ruby/pull/7182. I will add a test to that PR for this.
Updated by hsbt (Hiroshi SHIBATA) almost 2 years ago
- Status changed from Open to Assigned
- Assignee set to ko1 (Koichi Sasada)
Updated by reesericci (Reese Armstrong) 3 months ago ยท Edited
Hey y'all -
I'm commenting here to say that this bug seems to be the only way I was able to pass a Proc to a Ractor even though it doesn't reference self - so wondering what the path is for that instead of exploiting this bug. For context, here's my code:
class Transaction
def initialize(&block)
@block = Ractor.make_shareable(block.curry)
@original_state = nil
end
def apply(obj)
begin
@original_state = obj.dup
@new_obj = obj.deep_transform_values { |value| value = value.dup }
@block.call(@new_obj)
obj.replace(@new_obj)
rescue => e
puts e
rollback(obj)
raise e
end
end
end
Which then this entire object gets passed into a Ractor and that's where .apply()
is called.
Thanks,
--reese
Actions
Like0
Like0Like0Like0