/**
*
*/
package models.com.mc.actors;
import java.util.Arrays;
import java.util.List;
import akka.actor.*;
import akka.japi.Function;
import mc.messages.ResultMessage;
import mc.messages.TextMessage;
import models.com.mc.configs.ClassifiersConfig;
import models.com.mc.workers.MasterWorkerProtocol;
import scala.concurrent.duration.Duration;
import static akka.actor.SupervisorStrategy.Directive;
import static akka.actor.SupervisorStrategy.restart;
//import akka.routing.BroadcastGroup;
/**
* Actor for broadcasting and aggregating results
*
*/
public class BroadcastingActor extends UntypedActor {
ActorRef broadcastRouter;
ActorRef intermediateActor;
// Temporary ActorRefs - instead of broadcasting
ActorRef contextClassifierActor;
ActorRef genderClassifierActor;
ActorRef languageClassifierActor;
ActorRef spamClassifierActor;
// -- Temporary ActorRefs -- Ends
TextMessage tm;
int resultCount=0;
int retryCount =0;
@Override
public void preStart() throws Exception {
// Set ClassifierGroup to the context of IntermediateActor
getContext().actorOf(Props.create(ClassifiersGroup.class), "classifiers");
// Path list of the actors in ClassifierGroup actor - Temporary Removed
/*
List<String> paths = Arrays.asList(
"/user/" +self().path().parent().name() + "/" + self().path().name() + "/classifiers/ca1"
, "/user/" +self().path().parent().name() + "/" + self().path().name() + "/classifiers/ca2"
, "/user/" +self().path().parent().name() + "/" + self().path().name() + "/classifiers/ca3"
, "/user/" +self().path().parent().name() + "/" + self().path().name() + "/classifiers/ca4");
*/
// Broadcasting Router Temporary Disabled
// broadcastRouter = getContext().actorOf(new BroadcastGroup(paths).props(),
// "broadcastRouter");
// Temporary ActorRef initiation -- instead of Broadcasting
contextClassifierActor=getContext().actorOf(ClassifyingActor.props("context"), "ca1");;
genderClassifierActor=getContext().actorOf(ClassifyingActor.props("gender"), "ca2");
languageClassifierActor=getContext().actorOf(ClassifyingActor.props("language"), "ca3");
spamClassifierActor=getContext().actorOf(ClassifyingActor.props("spam"), "ca4");
// Temporary ActorRef initiation -- Ends
}
/* (non-Javadoc)
* @see akka.actor.UntypedActor#onReceive(java.lang.Object)
*/
@Override
public void onReceive(Object arg0) throws Exception {
try{
if(arg0 instanceof TextMessage)
{
tm = (TextMessage)arg0;
intermediateActor = getSender();
// Broadcasting Temporary Disabled
// broadcastRouter.tell(tm.getMessage(), getSelf());
// Temporary solution for Broadcasting
contextClassifierActor.tell(tm.getMessage(), getSelf());
genderClassifierActor.tell(tm.getMessage(), getSelf());
languageClassifierActor.tell(tm.getMessage(), getSelf());
spamClassifierActor.tell(tm.getMessage(), getSelf());
// Temporary solution for Broadcasting -- Ends
}
else if(arg0 instanceof ResultMessage)
{
ResultMessage rm = (ResultMessage)arg0;
if(rm.getResult()!=null){
String service = rm.getService();
if(service==ClassifiersConfig.CONTEXT_SERVICE){
tm.setContext(rm.getResult());
}
else if(service==ClassifiersConfig.GENDER_SERVICE){
tm.setGender(rm.getResult());
}
else if(service==ClassifiersConfig.LANGUAGE_SERVICE){
tm.setLanguage(rm.getResult());
}
else if(service==ClassifiersConfig.SPAM_SERVICE){
tm.setSpam(rm.getResult());
}
}
if(++resultCount == ClassifiersConfig.CLASSIFIER_COUNT)
sendBackFinalResult();
}else if(arg0 instanceof String){
//handle re-started Classifing Actor. Parameter: Service
if(retryCount <= ClassifiersConfig.CLASSIFIER_COUNT){
String service = (String) arg0;
if(service==ClassifiersConfig.CONTEXT_SERVICE){
contextClassifierActor.tell(tm.getMessage(), getSelf());
}
else if(service==ClassifiersConfig.GENDER_SERVICE){
genderClassifierActor.tell(tm.getMessage(), getSelf());
}
else if(service==ClassifiersConfig.LANGUAGE_SERVICE){
languageClassifierActor.tell(tm.getMessage(), getSelf());
}
else if(service==ClassifiersConfig.SPAM_SERVICE){
spamClassifierActor.tell(tm.getMessage(), getSelf());
}
retryCount++;
}else{
resultCount++;
}
}
}catch(Exception e){
intermediateActor.tell(new akka.actor.Status.Failure(e), getSelf());
throw e;
}
unhandled(arg0);
}
/**
* Send back the completed result to IntermediateActor
*/
private void sendBackFinalResult(){
// Need to tell IntermediateActor since it keeps waiting on this
intermediateActor.tell(tm, getSelf());
// Reset result counter
resultCount = 0;
}
/*
Supervisor Strategy to monitor child Actors and re-start the failed actors.
*/
@Override
public SupervisorStrategy supervisorStrategy() {
return new OneForOneStrategy(-1, Duration.Inf(),
new Function<Throwable, Directive>() {
@Override
public Directive apply(Throwable t) {
if (t instanceof ActorInitializationException)
return restart();
else if (t instanceof DeathPactException)
return restart();
else if (t instanceof Exception)
return restart();
else
return restart();
}
}
);
}
}