Subactor (worker) still works after Main actor Timeout in Java Akka -
i have implemented application in akka framework using java. have main actor calls sub-actor using 'ask' method , timeout after 60 seconds, worker calls java class method once receives message main actor.
now problem though main actor timed-out after 60 seconds still worker able talk java class method , in-turn method performing operations not required main actor cannot receive response though sub-actor returns due timeout.
is there anyway can kill worker or stop further processing if main actor timeout? checked methods recievetimeout()
, context.stop()
, poisonpill still no use.
appreciate support
code below
public class mainactor extends untypedactor { actorref subactorref; final timeout timeout = new timeout(duration.create(60, timeunit.seconds)); @override public void prestart() { subactorref = getcontext().actorof( springextprovider.get(actorsystem).props( "subactor"), "subactor"); } @override public void onreceive(object message) throws exception { if (message instanceof businessrequestvo) { businessrequestvo requestvo = (businessrequestvo) message; arraylist<future<object>> responsefutures = new arraylist<future<object>>(); // part of code timeout after 60seconds responsefutures.add(ask(subactorref,requestvo, timeout)); } } }
subactor class
public class subactor extends untypedactor { @resource @inject serviceadapter serviceadapter; @override public void onreceive(object message) throws exception { try{ if (message instanceof businessrequestvo) { businessrequestvo requestvo = (businessrequestvo)message // there no time out here waits synchronously // though main actor timeouts serviceresponse response = serviceadapter.getworkorder(requestvo); getsender().tell(response, actorref.nosender()); } catch (exception e) { getsender().tell(new akka.actor.status.failure(e), getself()); throw e; } } } }
adapter class
public class serviceadapterimpl implements serviceadapter{ public serviceresponse getworkorder(businessrequestvo request){ // code here along webservice calls } }
you can't child actor blocking, cannot process "stop" messages parent sends him (actors process messages 1 @ time before reading next 1 in mailbox).
your best bet wrap "slow" part of child's execution inside future can pipeto parent (see here details).
in way, if timeout expires, can have parent send custom "stop computing" message, , child actor can terminate future. see here how terminate future.
but introduce "dirty" states in application logic according specific computation gets terminated midway through execution.
on related note: why sending n requests same child actor (which made blocking)? equivalent sequential execution. should either make child actor non-blocking or (better) create blocking actor each request.
edit: requested op, added snippet. it's pseudo code mixing scala , java, i'm not super expert java syntax futures, use in scala, please adapt little:
if (message instanceof businessrequestvo) { new future ( businessrequestvo requestvo = (businessrequestvo)message try { serviceresponse response = serviceadapter.getworkorder(requestvo); getsender().tell(response, actorref.nosender()); } catch (exception e) { getsender().tell(new akka.actor.status.failure(e), getself()); throw e; } ) pipeto sender }
and in main (see here java's future.cancel)
if (timeout) future.cancel(true)
Comments
Post a Comment