Project

General

Profile

Actions

Bug #19374

open

Issue with Ractor.make_shareable with curried procs

Added by luke-gru (Luke Gruber) almost 2 years ago. Updated 4 months ago.

Status:
Assigned
Target version:
-
[ruby-core:112005]

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) 4 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

Also available in: Atom PDF

Like0
Like0Like0Like0