2016-06-14 4 views
0

Ich habe einen dedizierten Thread-Pool für Datenbankoperationen über die Play-Akka-Konfigurationsdatei zugewiesen. Im Moment injiziere ich die Dienste, die diesen Thread-Pool mit dem Actor-System benötigen und auf den Ausführungskontext zugreifen.Wie injiziere ich einen benutzerdefinierten Executor in eine Play-Anwendung?

public class ServiceA{ 

    final Executor executionContext; 

    @Inject 
    public ServiceA(ActorSystem system) { 
     this.executionContext = system.dispatchers().lookup("akka.actor.db-context"); 
} 

Aber das macht es schwierig, ServiceA zu testen. Was ich stattdessen tun möchte, ist nur den Executor direkt wie folgt injizieren:

Wie erreiche ich das? Ich habe versucht, ein Guice-Modul zu erstellen, um den Executor zu injizieren, aber es gibt Fehler aus, sich zu beschweren, dass es keine gestartete Anwendung gibt und keinen Zugriff auf ActorSystem hat, wenn es die Klassen bindet.

Antwort

1

Ich benutze ein Muster, wo ich EC bekommen kann, wo immer ich will. Ich erstelle ein ActorSystem in einem Singleton und bekomme es in meine Dienste injiziert.

Ich habe ein Design mit ActorSystems, Dispatcher und vieles mehr für die Überwachung. Schau dir das an und schau, ob du es integrieren kannst.

Wenn also MyActorSystem in Ihre Klasse injiziert wird, können Sie von dort auf das EC zugreifen. Werfen Sie einen Blick auf MyDispatcher und die Verwendung von EC:

@Singleton 
public class MyActorSystem implements IMyActorSystem{ 

    ActorSystem system; 
    public MyActorSystem() { 
     system = ActorSystem.create(); 

    } 

    public ActorRef create() { 
     final ActorRef actor = system.actorOf(
       Props.create(MyWorker.class).withDispatcher("my-disp") 
     ); 
     return actor; 
    } 

    public void shutdown(){ 
     system.shutdown(); 
    } 

    public ExecutionContextExecutor getDispatcher(){ 
     return system.dispatcher(); 
    } 
    } 

    public class MyDispatcher implements IMyDispatcher { 

    MyActorSystem system; 

    @Inject public MyDispatcher(MyActorSystem system) { 
     this.system = system; 
    } 


    public CompletableFuture<Object> dispatch(final Object story) { 
     List<CompletableFuture<Object>> futureList = new ArrayList<>(); 
     final ActorRef actor = system.create(); 
     final CompletableFuture<Object> completed = FutureConverter 
       .fromScalaFuture(Patterns.ask(actor, story, 50000)).executeOn(system.getDispatcher()) 
       .thenApply(i -> (Object) i); 
     return completed; 
    } 

    public ExecutionContextExecutor getDispatcher(){ 
     return system.getDispatcher(); 
    } 
} 
+0

Das ist eine Art, was ich am Ende auch getan habe. Jetzt müssen Sie Methoden wie getDispatcher() aufrufen, aber es ist eine verbesserte Lösung. Ich versuchte herauszufinden, ob es andere Möglichkeiten gäbe, den Executor direkt ohne zusätzliche Methodenaufrufe zu injizieren. – jesukumar

Verwandte Themen