java - Akka and Spring integration -
i trying akka working spring app. it's search app fits akka model perfectly. of illustration online , on typesafe regarding integration talk using akka extension inject spring application context. however, utilize actorsystem.actorof()
method create actors known expensive operation.
actorsystem scheme = ctx.getbean(actorsystem.class); system.actorof(.....)
see - https://github.com/typesafehub/activator-akka-java-spring/blob/master/src/main/java/sample/main.java
i want utilize actors process every web request passes authentication. above code, end creating root actor every single request not ideal.
any pointers appreciated.
the below doesn't reply original question reducing number of new actors need created when request comes web app.
to using akka router can simple next line of code:
getcontext().actorof(springextprovider.get(getcontext().system()).props("anotheractor.").withrouter(new roundrobinpool(100)), "another");
the akka docs provide much more detail regarding configuration though worth taking http://doc.akka.io/docs/akka/snapshot/java/routing.html. may preferable define behaviour via akka config file rather hard-coded app. can phone call like:
getcontext().actorof(springextprovider.get(getcontext().system()).props("anotheractor.").withrouter(new fromconfig()), "another");
..and define type , behviour of router in application.conf file.
if you've not considered it, it's worth checking out how create web rerquests asynchronous. 1 approach utilize spring's deferredresult , pass instance of actor , set result on completion of search request.
--update 20/11--
i think why actor selection isn't working because trying utilize bean name, not actor name pacth actor selection. when creating router don't specify actor name given name internally akka, soemthing "$a".
to illustrate, if create actor with:
actorsystem.actorof(this.get(actorsystem).props(applicationcontext, "bean_name"), "actorname");
then should able perform actor selection with:
actorsystem.actorselection("actorname");
alternatively create above router actor once, , re-use in every request made spring mvc web service, create in spring @configuration class , expose actorref bean can inject spring @controller class. next quick illustration have created frmo memory please create sure tested/compiles etc.
@configuration public class config { @autowired private actorsystem actorsystem; @bean(name = "routeractorref") public actorref routeractorref() { getcontext().actorof(springextprovider.get(actorsystem).props("anotheractor").withrouter(new roundrobinpool(100)), "another"); } }
you can inject spring bean writing like:
@autowired @qualifier("routeractorref") private actorref routeractorref;
it should noted feasible top-level actors, it's possible lower level actors become quite tricky manage efficiently.
-- original reply --
the illustration in main method link showing how initial top-level actor created supervised scheme based "user" actor. quite simple illustration demonstrates creating spring managed actor named countingactor spring managed bean named countingservice injected it.
to take illustration farther define actor looks similar countingactor e.g.
@named("anotheractor") @scope("prototype") class anotheractor extends untypedactor { // service automatically injected final anotherservice anotherservice; @inject public anotheractor(@named("anotherservice") anotherservice anotherservice) { this.anotherservice = anotherservice; } @override public void onreceive(object message) throws exception { if (message == "dosomething") { anotherservice.dosomething(); } else { unhandled(message); } } }
i have assumed there spring service bean called anotherservice has method dosomething() injected when anotheractor created.
then in countingactor can create anotheractor so:
@named("countingactor") @scope("prototype") class countingactor extends untypedactor { public static class count {} public static class {} // service automatically injected final countingservice countingservice; @inject public countingactor(@named("countingservice") countingservice countingservice) { this.countingservice = countingservice; } private int count = 0; @override public void onreceive(object message) throws exception { if (message instanceof count) { count = countingservice.increment(count); // create anotheractor here kid of countingactor using countingactor's context actorref anotheractor = getcontext().actorof(springextprovider.get(system).props("anotheractor"), "another"); anotheractor.tell("dosomething", getself()); } else if (message instanceof get) { getsender().tell(count, getself()); } else { unhandled(message); } } }
the key difference between actor creation here , 1 main utilize of getcontext().actorof(...) instead of system.actorof(...). using getcontext() causes new actor created kid of counteractor, not top level "user" actor.
there description of behaviour in official akka docs: http://doc.akka.io/docs/akka/snapshot/java/untyped-actors.html#creating-actors-with-props
java spring akka
No comments:
Post a Comment