2016-06-14 3 views
0

Я назначил выделенный пул потоков для операций с базой данных через файл конфигурации play-akka. На данный момент я ввожу услуги, которые требуют этого пула потоков с системой актеров и доступа к контексту выполнения.Как добавить пользовательский Executor в приложение для воспроизведения?

public class ServiceA{ 

    final Executor executionContext; 

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

Но это затрудняет тестирование ServiceA. То, что я хотел бы сделать вместо этого просто впрыснуть Исполнитель непосредственно, как это:

public class ServiceA{ 

    final Executor executionContext; 

    @Inject 
    public ServiceA(Executor dbExecutionCtx) { 
     this.executionContext = dbExecutionCtx; 
} 

Как этого добиться? Я попытался создать модуль guice для инъекции Executor, но он ошибается, заявляя, что нет запущенного приложения и не имеет доступа к ActorSystem, когда это делает его обязательным для классов.

ответ

1

Я использую шаблон, где я могу получить EC в любом месте. Я создаю ActorSystem в Singleton и получаю его впрыскивание в мои сервисы.

У меня есть дизайн с ActorSystems, диспетчерами и многое другое для мониторинга. Посмотрите на это и посмотрите, можете ли вы его интегрировать.

Итак, если MyActorSystem вводится в ваш класс, вы можете получить доступ к EC от него. Взгляните на MyDispatcher и использование 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

Это то, что я тоже сделал. Теперь вам нужно вызвать методы, такие как getDispatcher(), но это улучшенное решение. Я пытался исследовать, есть ли другие способы просто вводить исполнителя непосредственно без каких-либо дополнительных вызовов метода. – jesukumar