Project

General

Profile

Feature #19326

Updated by sdwolfz (Codruț Gușoi) almost 2 years ago

Example 1: 
 ```ruby 
 class Worker 
   def initialize(&block) 
     @block = block 
   end 

   def run 
     Ractor.new(@block, &:call) 
   end 
 end 

 worker = Worker.new { 1 } 
 puts worker.run.take 
 ``` 

 Errors with: 
 ``` 
 <internal:ractor>:271:in `new': allocator undefined for Proc (TypeError) 
         from scripts/run.rb:9:in `run' 
         from scripts/run.rb:14:in `<main>' 
 ``` 

 Example 2: 
 ```ruby 
 class Worker 
   def initialize(&block) 
     @block = Ractor.make_shareable(block) 
   end 

   def run 
     Ractor.new(@block, &:call) 
   end 
 end 

 worker = Worker.new { 1 } 
 puts worker.run.take 
 ``` 

 Errors with: 

 ``` 
 <internal:ractor>:820:in `make_shareable': Proc's self is not shareable: #<Proc:0x00007f00394c38b8 scripts/run.rb:13> (Ractor::IsolationError) 
         from scripts/run.rb:5:in `initialize' 
         from scripts/run.rb:13:in `new' 
         from scripts/run.rb:13:in `<main>' 
 ``` 

 Example 3: 
 ```ruby 
 class Worker 
   def initialize(&block) 
     @block = Ractor.make_shareable(block) 
   end 

   def run 
     Ractor.new(@block, &:call) 
   end 
 end 

 worker = Ractor.current.instance_eval { Worker.new { 1 } } 
 puts worker.run.take 
 ``` 

 Works, but having `Ractor.current.instance_eval` as a wrapper around the block is not ideal, as Ractor is supposed to be only an implementation detail in Worker. 

 I know about https://bugs.ruby-lang.org/issues/18243 and the discussion around `proc.bind(nil)`. That would actually be ideal, as for the purposes if why I want this functionality I don't care what `self` is in a block, and the less it has access to the better. 

 The general idea of Worker is to have a Ractor be able to lazily execute an arbitrary proc. And all the bindings it would need would be passed explicitly, either through `args` in the constructor or through `send`/`receive`, so `self` would really not matter. 

 The benefit: this would make it so concurrent code can be more easily be implemented with Ractors as currently you can execute an arbitrary proc by passing it to a Thread (but you don't get the nice data isolation).

Back