🎓 A1Learner
🔍
0 of 28 lessons completed

Ruby Ractors

A ractor is a unit of work that runs in parallel with the main program. Ractors share nothing by default, so values cross only through arguments, sends, and take.

Passing a value in and taking the answer

The first line turns the experimental warning off. The value 21 goes into the ractor as the block parameter, and take collects the doubled answer.

Warning[:experimental] = false
ractor = Ractor.new(21) do |number|
  number * 2
end
puts ractor.take

Waiting for a send with Ractor.receive

Ractor.receive pauses the ractor until a value arrives. The send call hands the word in, and take collects the uppercased result.

Warning[:experimental] = false
ractor = Ractor.new do
  word = Ractor.receive
  word.upcase
end
ractor.send("hello")
puts ractor.take

Two ractors, two takes

Each ractor runs its own block on its own value. The main program takes the answers one at a time, in the order it asks.

Warning[:experimental] = false
first = Ractor.new(10) do |number|
  number + 1
end
second = Ractor.new(20) do |number|
  number + 2
end
puts first.take
puts second.take

An outer array stays out of reach

The block tries to read the WORDS array through its constant name. The array is not shareable, so the read raises Ractor::IsolationError and the rescue hands back only the error class.

Warning[:experimental] = false
WORDS = ["red", "blue"]
ractor = Ractor.new do
  begin
    WORDS.length
  rescue => e
    e.class
  end
end
puts ractor.take

Example

Warning[:experimental] = false
doubler = Ractor.new(15) do |number|
  number * 2
end
greeter = Ractor.new do
  name = Ractor.receive
  "Hello, #{name}"
end
greeter.send("Ana")
puts doubler.take
puts greeter.take

Key points

  • Ractor.new starts a ractor and hands it a block to run.
  • A value passed to Ractor.new arrives inside as the block parameter.
  • take waits for a ractor to finish and returns its last value.
  • Ractor.receive waits inside a ractor for a value sent with send.
  • A ractor block cannot read an outer object that is not shareable.

In this example, one ractor doubles the value passed into it. A second ractor waits with Ractor.receive for a name and builds a greeting from it. The main program sends the name, then takes both answers in turn.

Note

The first line of every ractor program here turns the experimental warning off.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

A program starts a ractor with Ractor.new(6) and a block that doubles its parameter. What does ractor.take return?