Skip to content

Instantly share code, notes, and snippets.

@danielsz
Created November 5, 2012 15:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save danielsz/4017607 to your computer and use it in GitHub Desktop.
Save danielsz/4017607 to your computer and use it in GitHub Desktop.
Concurrent "Hello, world" with Celluloid, an actor library for Ruby

The premise of this exercise is contained in Daniel Himelein's quote:

"The first thing I always do when playing around with a new software platform is to write a concurrent "Hello World" program. The program works as follows: One active entity (e.g. thread, Erlang process, Goroutine) has to print "Hello " and another one "World!\n" with the two active entities synchronizing with each other so that the output always is "Hello World!\n". Here is the concurrent Hello World program in Go, Erlang and in C++ using the Mindroid framework."

Original post

Here is a Hello World example in Ruby/Celluloid. Five, actually.

require 'celluloid'
class Greeter
def initialize(msg)
@msg = msg
end
def greet
@msg
end
end
class Hello < Greeter
include Celluloid
end
class World < Greeter
include Celluloid
def initialize(msg)
super
wait_for_hello!
end
def wait_for_hello
loop do
receive { |msg| puts "#{msg} #{greet}" }
end
end
end
hello = Hello.new "hello"
world = World.new "world"
100.times do
world.mailbox << hello.greet
end
hello = Hello.new "hello"
world = World.new "world"
futures = []
100.times do
futures << hello.future.greet
end
futures.each { |future| world.mailbox << future.value }
sleep 1
exit
hello = Hello.new "hello"
world = World.new "world"
futures = []
100.times do
futures << Celluloid::Future.new { world.mailbox << hello.greet }
end
futures.each { |future| future.value }
class Runner
include Celluloid
def initialize
@hello = Actor[:hello]
@world = Actor[:world]
run!
end
def run
futures = []
100.times do
futures << @hello.future.greet
end
futures.each { |future| @world.mailbox << future.value }
end
end
class MyGroup < Celluloid::SupervisionGroup
supervise Hello, :as => :hello, :args => ["hello"]
supervise World, :as => :world, :args => ["world"]
supervise Runner
end
MyGroup.run!
sleep 1
exit
## if we change the Hello greeter to this
class Hello < Greeter
include Celluloid
def initialize(msg)
super
@world = Actor[:world]
end
def sync
@world.mailbox << greet
end
end
## We can then write this:
world = World.new "world"
Celluloid::Actor[:world] = world
hello = Hello.new "hello"
100.times do
hello.async.sync
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment