An introduction to Celluloid, a concurrent programming framework for Ruby based on the Actor Model. This is a version of the talk I gave at MWRC, but tailored for JRuby users, and with a much expanded intro to DCell.
import akka.util.Timeout import akka.util.duration._ case class Request(payload: String) case class Response(payload: String) trait Service { def request(r: Request): Future[Response] } class ServiceImpl extends Service { val actor = { val ctx = TypedActor.context ctx.actorOf(Props[ServiceActor]) } implicit val timeout = Timeout(10 seconds) def request(req: Request): Future[Response] = (actor ? req).mapTo[Response] } class ServiceActor extends Actor { def receive = { case Request(payload) => sender ! Response(payload) } } object Main extends App { val system = ActorSystem("TypedActorDemo") val service: Service = TypedActor(system).typedActorOf( TypedProps[ServiceImpl]() ) val req = Request("hello world!") service.request(req) onSuccess { case Response(response) => println(response) system.shutdown() } }
= Mutex.new end def [](*keys) @mutex.synchronize { keys.inject(@outer) { |h,k| h[k] } } end def []=(*args) @mutex.synchronize do value = args.pop raise ArgumentError, "wrong number of arguments (1 for 2)" if args.empty? key = args.pop hash = args.inject(@outer) { |h,k| h[k] ||= {} } hash[key] = value end end def inspect; @mutex.synchronize { super }; end end
{} end def [](*keys) keys.inject(@outer) { |h,k| h[k] } end def []=(*args) value = args.pop raise ArgumentError, "wrong number of arguments (1 for 2)" if args.empty? key = args.pop hash = args.inject(@outer) { |h,k| h[k] ||= {} } hash[key] = value end end
def greet(interested_party) "Hello #{interested_party.name}, I'm #{name}" end end class Joe < Person; end class Mike < Person def greet(other) super << "\n" << other.greet(current_actor) end end mike = Mike.new joe = Joe.new puts mike.greet(joe)
def greet(interested_party) "Hello #{interested_party.name}, I'm #{name}" end end class Joe < Person; end class Mike < Person def greet(other) super << "\n" << other.greet(current_actor) end end mike = Mike.new joe = Joe.new puts mike.greet(joe)
over the network, and you don't have to worry about the networking gunk, and you don't have to worry about finding them, and you don't have to worry about anything. It's just as if you messaged an object that's right next door." --Steve Jobs describing NeXT Portable Distributed Objects
=> 'itchy', :addr => 'tcp:// 127.0.0.1:7777' I, [2012-05-09T10:20:46.999000 #52416] INFO -- : Connected to itchy => #<Celluloid::Supervisor(DCell::Group):0x836> Note itchy is on port 7777
=> 'scratchy', :addr => 'tcp:// 127.0.0.1:7778', :directory => {:id => 'itchy', :addr => 'tcp://127.0.0.1:7777'} I, [2012-05-09T10:26:42.322000 #52555] INFO -- : Connected to itchy I, [2012-05-09T10:26:42.331000 #52555] INFO -- : Connected to scratchy => #<Celluloid::Supervisor(DCell::Group):0x838> Note scratchy is on port 7778