2015-11-11 2 views
0

все контроллеры моего приложения (Play Framework 2.2.4, Java) возвращают F.Promise: теперь есть один контроллер, в котором я переключаюсь на другой контекст akka, поскольку его время вычисления может быть больше. Переключение контекста довольно straigthforward, как вы можете использовать API:Play Framework: обработка таймаута по сравнению с контрольным обещанием

return F.Promise.promise(...,executionContext) 

и настроить пользовательский ExecutionContext в application.conf. Теперь проблема возникает, когда вычисление длиннее заданного количества времени (давайте сделаем это 20 секунд): я не могу выполнить тайм-аут Promise. Обратите внимание, что я не хочу ссылаться на get (20, TimeUnit.SECONDS метод) на обещании, как я уверен, что игра будет делать, что в его guts.I искала какое-либо свойство конфигурации в AKKA executionService и нашел этот

thread-pool-executor { 
    # Keep alive time for threads 
    keep-alive-time = 60s 

    # Min number of threads to cap factor-based core number to 
    core-pool-size-min = 8 

    # The core pool size factor is used to determine thread pool core size 
    # using the following formula: ceil(available processors * factor). 
    # Resulting size is then bounded by the core-pool-size-min and 
    # core-pool-size-max values. 
    core-pool-size-factor = 3.0 

    # Max number of threads to cap factor-based number to 
    core-pool-size-max = 64 

    # Minimum number of threads to cap factor-based max number to 
    # (if using a bounded task queue) 
    max-pool-size-min = 8 

    # Max no of threads (if using a bounded task queue) is determined by 
    # calculating: ceil(available processors * factor) 
    max-pool-size-factor = 3.0 

    # Max number of threads to cap factor-based max number to 
    # (if using a bounded task queue) 
    max-pool-size-max = 64 

    # Specifies the bounded capacity of the task queue (< 1 == unbounded) 
    task-queue-size = -1 

    # Specifies which type of task queue will be used, can be "array" or 
    # "linked" (default) 
    task-queue-type = "linked" 

    # Allow core threads to time out 
    allow-core-timeout = on 
    } 

но ни Keep-Alive время ни allow-core-timeout Свойства полезны для ожидания длинных вычислений.

Я попытался изменить тип возвращаемого на что-то вроде:

F.Promise<Result> original = F.Promise.promise(...,customExecutionService); 
return F.promise.timeout(original,10,TimeUnit.SECONDS); 

, но это только отсрочить исполнение на 10 секунд (документация метод тайм-аут очень сбивает с толку)

Другой фрагмент кода я попытался это. :

F.Promise<Result> original = F.Promise.promise(...,customExecutionService); 
    return F.promise.timeout(original,10,TimeUnit.SECONDS).get(10,TimeUnit.SECONDS); 

но этот тайм-аут внешний обертка обещает.

Итак, теперь я прихожу к выводу, что мне нужно написать собственное собственное выполнение службы, которая устанавливает прослушиватель тайм-аута и сама генерирует исключение TimeoutException, но я уверен, что есть какой-то более простой путь для достижения это.

ответ

0

Я нашел одно решение, обернув оригинальный ответ (тот, который не делает тайм-аута) со следующим кодом:

Future<T> error = after(Duration.create(delay,unit),Akka.system().scheduler(),main, 
       Futures.failed(new TimeoutException("Future timed out"))); 

return Promise.wrap(Futures.firstCompletedOf(
    Lists.newArrayList(original.wrapped(),error), main)); 

`` `

Где основной является основным контекстом выполнения , после взято из akka Patterns. В принципе, если первоначальное обещание занимает больше, чем , длительность, принятая в ошибке, вступает в игру, бросая исключение таймаута.

Я помещал это в фильтр, поэтому каждый контроллер, аннотированный этим фильтром, имеет одинаковое поведение.

Смежные вопросы