Skip to content

Instantly share code, notes, and snippets.

@coffeeaddict
Created March 6, 2012 16:09
Show Gist options
  • Save coffeeaddict/1987094 to your computer and use it in GitHub Desktop.
Save coffeeaddict/1987094 to your computer and use it in GitHub Desktop.
Akka 2.0 experiment
# A JRuby alternative for the Akka.io homepage scala and java examplatory code.
require 'java'
require './lib/scala-library.jar'
require './lib/akka/akka-actor-2.0.jar'
module Akka
include_package 'akka.actor'
end
class Greeting
attr_reader :who
def initialize(who)
@who = who
end
end
class Greeter < Akka::UntypedActor
def self.create(*args)
self.new(*args)
end
def onReceive(message)
if message.kind_of? Greeting
File.open("log", File::CREAT|File::APPEND|File::WRONLY) do |f|
f.puts "Hello; #{message.who}"
end
else
unhandled(message)
end
end
end
system = Akka::ActorSystem.create("MySystem")
greeter = system.actorOf(Akka::Props.new(Greeter), "greeter")
greeter.tell(Greeting.new("Charlie Parker"))
system.shutdown
# Getting started from akka.io documentation - in JRuby flavor
require 'java'
require './lib/scala-library.jar'
require './lib/akka/akka-actor-2.0.jar'
module Akka
include_package 'akka.actor'
java_import 'akka.routing.RoundRobinRouter'
end
class Calculate; end
class Work
attr_reader :start, :elements
def initialize(start, elements)
@start = start
@elements = elements
end
end
class Result
attr_reader :value
def initialize(result)
@value = result
end
end
class PiApprox
attr_reader :pi, :duration
def initialize(pi, duration)
@pi = pi
@duration = duration
end
def to_a
[ @pi, @duration ]
end
end
class Worker < Akka::UntypedActor
def self.create(*a) self.new(*a) end
def initialize(*args)
$stderr.puts "Creating a worker [#{args}]"
super
end
def calculatePiFor(start, nrOfElements)
((start * nrOfElements)...((start + 1) * nrOfElements)).inject(0) do |acc, i|
acc + 4.0 * (1 - (i.modulo 2) * 2) / (2 * i + 1)
end
end
def onReceive(message)
if message.is_a? Work
res = calculatePiFor message.start, message.elements
getSender.tell Result.new(res), getSelf
else
unhandled message
end
end
end
class Master < Akka::UntypedActor
def self.create(*a) self.new(*a) end
def initialize(workers, messages, elements, listener)
super()
@workers = workers
@messages = messages
@elements = elements
@listener = listener
$stderr.puts "Starting #{@workers} workers, for #{@messages} messages to find #{@elements} elements"
@workerRouter = self.getContext().actorOf(
Akka::Props.new(Worker).withRouter(Akka::RoundRobinRouter.new(@workers)),
"workerRouter"
);
@pi = 0
@results = 0
@start = Time.now
return self
end
def onReceive(message)
if message.is_a? Calculate
if @messages.nil?
$stderr.puts "Receiving a calculate without config!"
return unhandled(message)
end
@messages.times do |i|
@workerRouter.tell(Work.new(i, @elements), self.getSelf())
end
elsif message.is_a? Result
@pi += message.value
@results += 1
if ( @results == @messages )
@listener.tell PiApprox.new(@pi, Time.now - @start), getSelf
getContext.stop getSelf
end
else
unhandled(message)
end
end
end
class Listener < Akka::UntypedActor
def self.create(*a) self.new(*a) end
def initialize(*a)
super
end
def onReceive(message)
if message.is_a? PiApprox
$stdout.puts "\n\tPi approximation: \t\t%s\n\tCalculation time: \t%.2fs" % message.to_a
getContext.system.shutdown;
else
unhandled(message)
end
end
end
class MasterFactory
include Akka::UntypedActorFactory
def initialize(workers, elements, messages, listener)
@workers = workers
@elements = elements
@messages = messages
@listener = listener
end
def create(*args)
Master.new(@workers, @elements, @messages, @listener)
end
end
class Pi
def self.calculate(workers, elements, messages)
system = Akka::ActorSystem.create "PiSystem"
listener = system.actorOf Akka::Props.new(Listener), "listener"
master = system.actorOf(
Akka::Props.new(MasterFactory.new(workers, elements, messages, listener)),
"master"
)
master.tell Calculate.new
end
end
Pi.calculate(4, 100, 100)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment