Last active
July 23, 2018 13:27
-
-
Save timyates/10470012 to your computer and use it in GitHub Desktop.
Pi Approximation With Akka and Groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Grab( 'com.typesafe.akka:akka-actor_2.10:2.3.2' ) | |
@Grab( 'com.typesafe:config:1.2.0' ) | |
import groovy.transform.Immutable | |
import akka.actor.ActorRef | |
import akka.actor.ActorSystem | |
import akka.actor.Props | |
import akka.actor.UntypedActor | |
import akka.actor.UntypedActorFactory | |
import akka.routing.RoundRobinRouter | |
import scala.concurrent.duration.Duration | |
import java.util.concurrent.TimeUnit | |
import com.typesafe.config.ConfigFactory | |
// Message classes | |
@Immutable class Calculate {} | |
@Immutable class Work { int start, nrOfElements } | |
@Immutable class Result { double value } | |
@Immutable(knownImmutables=['duration']) class PiApproximation { double pi ; Duration duration } | |
// Main worker | |
class Worker extends UntypedActor { | |
private double calculatePiFor( int start, int nrOfElements ) { | |
((start * nrOfElements)..((start + 1) * nrOfElements - 1)).inject( 0.0 ) { acc, i -> | |
acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1) | |
} | |
} | |
void onReceive( message ) { | |
switch( message ) { | |
case Work: | |
sender.tell( new Result( calculatePiFor( message.start, message.nrOfElements ) ), self ) | |
break | |
default: | |
unhandled( message ) | |
} | |
} | |
} | |
class Master extends UntypedActor { | |
private final int nrOfMessages | |
private final int nrOfElements | |
private double pi | |
private int nrOfResults | |
private final long start = System.currentTimeMillis() | |
private final ActorRef listener | |
private final ActorRef workerRouter | |
public Master( int nrOfWorkers, int nrOfMessages, int nrOfElements, ActorRef listener ) { | |
this.nrOfMessages = nrOfMessages | |
this.nrOfElements = nrOfElements | |
this.listener = listener | |
workerRouter = context.actorOf( Props.create( Worker ).withRouter( new RoundRobinRouter( nrOfWorkers ) ), "workerRouter" ) | |
} | |
void onReceive( message ) { | |
switch( message ) { | |
case Calculate: | |
nrOfMessages.times { workerRouter.tell( new Work( it, nrOfElements ), self ) } | |
break | |
case Result: | |
pi += message.value | |
if( ++nrOfResults >= nrOfMessages ) { | |
listener.tell new PiApproximation( pi, Duration.create( System.currentTimeMillis() - start, TimeUnit.MILLISECONDS ) ), self | |
context.stop( self ) | |
} | |
default: | |
unhandled( message ) | |
} | |
} | |
} | |
class Listener extends UntypedActor { | |
void onReceive( message ) { | |
switch( message ) { | |
case PiApproximation: | |
println "Pi approx $message.pi in $message.duration" | |
context.system().shutdown() | |
break | |
default: | |
unhandled( message ) | |
} | |
} | |
} | |
def cl = this.class.classLoader | |
ActorSystem.create( 'PiSystem', ConfigFactory.load( cl ), cl ).with { system -> | |
system.actorOf( Props.create( Listener ), 'listener' ).with { listener -> | |
system.actorOf( | |
Props.create( | |
[ create:{ -> new Master( 4, 1000, 1000, listener ) } ] as UntypedActorFactory | |
), 'master' ).with { master -> | |
master.tell new Calculate(), listener | |
} | |
} | |
system.awaitTermination() | |
} |
Not sure why, but using the groovy eclipse plugin 2.8.0-01, this example now generates java.lang.ArrayIndexOutOfBoundsException when generating interface types.
Seems like it might have something to do with the Props.create of an UntypedActorFactory?
java.lang.ArrayIndexOutOfBoundsException: 1
at org.codehaus.groovy.vmplugin.v5.Java5.makeInterfaceTypes(Java5.java:392)
at org.codehaus.groovy.vmplugin.v5.Java5.configureClassNode(Java5.java:375)
at org.codehaus.groovy.ast.ClassNode.lazyClassInit(ClassNode.java:258)
at org.codehaus.groovy.ast.ClassNode.getInterfaces(ClassNode.java:353)
at org.codehaus.groovy.ast.ClassNode.declaresInterface(ClassNode.java:945)
at org.codehaus.groovy.ast.ClassNode.implementsInterface(ClassNode.java:925)
at org.codehaus.groovy.ast.ClassNode.isDerivedFromGroovyObject(ClassNode.java:915)
at org.codehaus.groovy.classgen.AsmClassGenerator.loadWrapper(AsmClassGenerator.java:1542)
at org.codehaus.groovy.classgen.asm.CallSiteWriter.makeCallSite(CallSiteWriter.java:303)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCachedCall(InvocationWriter.java:245)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCall(InvocationWriter.java:329)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCall(InvocationWriter.java:76)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeInvokeMethodCall(InvocationWriter.java:60)
at org.codehaus.groovy.classgen.asm.InvocationWriter.writeInvokeMethod(InvocationWriter.java:382)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitMethodCallExpression(AsmClassGenerator.java:650)
at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:64)
at org.codehaus.groovy.classgen.asm.CallSiteWriter.makeCallSite(CallSiteWriter.java:301)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCachedCall(InvocationWriter.java:245)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCall(InvocationWriter.java:329)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCall(InvocationWriter.java:76)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeInvokeMethodCall(InvocationWriter.java:60)
at org.codehaus.groovy.classgen.asm.InvocationWriter.writeInvokeMethod(InvocationWriter.java:382)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitMethodCallExpression(AsmClassGenerator.java:650)
at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:64)
at org.codehaus.groovy.classgen.asm.CallSiteWriter.prepareSiteAndReceiver(CallSiteWriter.java:232)
at org.codehaus.groovy.classgen.asm.CallSiteWriter.prepareSiteAndReceiver(CallSiteWriter.java:221)
at org.codehaus.groovy.classgen.asm.CallSiteWriter.makeCallSite(CallSiteWriter.java:270)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCachedCall(InvocationWriter.java:245)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCall(InvocationWriter.java:329)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCall(InvocationWriter.java:76)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeInvokeMethodCall(InvocationWriter.java:60)
at org.codehaus.groovy.classgen.asm.InvocationWriter.writeInvokeMethod(InvocationWriter.java:382)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitMethodCallExpression(AsmClassGenerator.java:650)
at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:64)
at org.codehaus.groovy.classgen.asm.StatementWriter.writeReturn(StatementWriter.java:582)
at org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.writeReturn(OptimizingStatementWriter.java:316)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitReturnStatement(AsmClassGenerator.java:507)
at org.codehaus.groovy.ast.stmt.ReturnStatement.visit(ReturnStatement.java:47)
at org.codehaus.groovy.classgen.asm.StatementWriter.writeBlockStatement(StatementWriter.java:81)
at org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.writeBlockStatement(OptimizingStatementWriter.java:155)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitBlockStatement(AsmClassGenerator.java:457)
at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:69)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:101)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:112)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitStdMethod(AsmClassGenerator.java:321)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitConstructorOrMethod(AsmClassGenerator.java:278)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:123)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitMethod(AsmClassGenerator.java:398)
at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1055)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:50)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitClass(AsmClassGenerator.java:180)
at org.codehaus.groovy.control.CompilationUnit$15.call(CompilationUnit.java:794)
at org.codehaus.groovy.control.CompilationUnit$15.call(CompilationUnit.java:811)
at org.codehaus.groovy.control.CompilationUnit$15.call(CompilationUnit.java:811)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1036)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:572)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:550)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:527)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:279)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:258)
at groovy.lang.GroovyShell.parseClass(GroovyShell.java:613)
at groovy.lang.GroovyShell.run(GroovyShell.java:480)
at groovy.lang.GroovyShell.run(GroovyShell.java:163)
at groovy.lang.GroovyShell$run.call(Unknown Source)
at groovy.ui.Console$_runScriptImpl_closure17.doCall(Console.groovy:951)
at groovy.ui.Console$_runScriptImpl_closure17.doCall(Console.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:909)
at groovy.lang.Closure.call(Closure.java:411)
at groovy.lang.Closure.call(Closure.java:405)
at groovy.lang.Closure.run(Closure.java:492)
at java.lang.Thread.run(Thread.java:722)
java.lang.ArrayIndexOutOfBoundsException: 1
Thanks! I guess GPars for Groovy can do that as well, is that right?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example taken from http://doc.akka.io/docs/akka/2.0.2/intro/getting-started-first-java.html