5.3 Tips and Tricks - Reference Documentation
Authors: The Whole GPars Gang
Version: 1.2.0
5.3 Tips and Tricks
Structuring actor's code
When extending the DefaultActor class, you can call any actor's methods from within the act() method and use the react() or loop() methods in them.class MyDemoActor extends DefaultActor { protected void act() { handleA() } private void handleA() { react {a -> handleB(a) } } private void handleB(int a) { react {b -> println a + b reply a + b } } }final def demoActor = new MyDemoActor() demoActor.start()Actors.actor { demoActor 10 demoActor 20 react { println "Result: $it" } }.join()
Actor demoActor = Actors.actor {
delegate.metaClass {
handleA = {->
react {a ->
handleB(a)
}
} handleB = {a ->
react {b ->
println a + b
reply a + b
}
}
} handleA()
}Actors.actor {
demoActor 10
demoActor 20
react {
println "Result: $it"
}
}.join()
Closure handleB = {a ->
react {b ->
println a + b
reply a + b
}
}Closure handleA = {->
react {a ->
handleB(a)
}
}Actor demoActor = Actors.actor {
handleA.delegate = delegate
handleB.delegate = delegate handleA()
}Actors.actor {
demoActor 10
demoActor 20
react {
println "Result: $it"
}
}.join()
Event-driven loops
When coding event-driven actors you have to have in mind that calls to react() and loop() methods have slightly different semantics. This becomes a bit of a challenge once you try to implement any types of loops in your actors. On the other hand, if you leverage the fact that react() only schedules a continuation and returns, you may call methods recursively without fear to fill up the stack. Look at the examples below, which respectively use the three described techniques for structuring actor's code.A subclass of DefaultActorclass MyLoopActor extends DefaultActor { protected void act() { outerLoop() } private void outerLoop() { react {a -> println 'Outer: ' + a if (a != 0) innerLoop() else println 'Done' } } private void innerLoop() { react {b -> println 'Inner ' + b if (b == 0) outerLoop() else innerLoop() } } }final def actor = new MyLoopActor().start() actor 10 actor 20 actor 0 actor 0 actor.join()
Actor actor = Actors.actor { delegate.metaClass { outerLoop = {-> react {a -> println 'Outer: ' + a if (a!=0) innerLoop() else println 'Done' } } innerLoop = {-> react {b -> println 'Inner ' + b if (b==0) outerLoop() else innerLoop() } } } outerLoop() }actor 10 actor 20 actor 0 actor 0 actor.join()
Closure innerLoopClosure outerLoop = {-> react {a -> println 'Outer: ' + a if (a!=0) innerLoop() else println 'Done' } }innerLoop = {-> react {b -> println 'Inner ' + b if (b==0) outerLoop() else innerLoop() } }Actor actor = Actors.actor { outerLoop.delegate = delegate innerLoop.delegate = delegate outerLoop() }actor 10 actor 20 actor 0 actor 0 actor.join()
class MyLoopingActor extends DefaultActor { protected void act() { loop { outerLoop() } } private void outerLoop() { react {a -> println 'Outer: ' + a if (a!=0) innerLoop() else println 'Done for now, but will loop again' } } private void innerLoop() { react {b -> println 'Inner ' + b if (b == 0) outerLoop() else innerLoop() } } }final def actor = new MyLoopingActor().start() actor 10 actor 20 actor 0 actor 0 actor 10 actor.stop() actor.join()