I'd like to have my master actor terminate all slave actors as soon as the first one finishes its work.
However, I have no idea how I could send a broadcast from my master to all the slaves. Is there a function or programming pattern for this?
Another way to solve this problem could be to give the master a list of all slaves and loop through them, sending each a message to terminate, however the slaves also need the master as an attribute and I think this is a problem:
import groovyx.gpars.actor.Actor
import groovyx.gpars.actor.DefaultActor
class Slave extends DefaultActor {
Actor master
int t
void act() {
t = new Random().nextInt(1337)
println "It's me, $t"
master.send 0
}
}
class Master extends DefaultActor {
List slaves
void afterStart() {
println "Master initialized!"
}
void killTheSlaves() {
for (i in 0..slaves.size()-1){
slaves[i].send -1
}
}
void act() {
react { int num ->
if (num == 0)
killTheSlaves()
}
}
}
def sl = new Slave().start()
def ma = new Master(slaves: [sl]).start()
sl.master = ma
This code does not compile.
Error message:
An exception occurred in the Actor thread Actor Thread 2 java.lang.NullPointerException: Cannot invoke method send() on null object at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:35) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at Slave.act(ConsoleScript14:11) at groovyx.gpars.actor.DefaultActor.handleStart(DefaultActor.java:342) at groovyx.gpars.actor.AbstractLoopingActor$1.handleMessage(AbstractLoopingActor.java:70) at groovyx.gpars.util.AsyncMessagingCore.run(AsyncMessagingCore.java:132) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
Looks like I cannot set sl.master after I created the slave.
Is there a workaround for this?
Any help is greatly appreciated.
Thank you in advance!