Какой хороший, надежный способ ASYNC проверить, существуют ли URL-адреса с контроллера Play? - PullRequest
1 голос
/ 09 января 2012

Первоначально я пытался это сделать:

private static boolean checkUrlsAreReachable(String... urls) {
    checkArgument(urls.length > 0);

    List<F.Promise<WS.HttpResponse>> promises = newArrayList();
    for (String url : urls) {
        promises.add(WS.url(url).followRedirects(true).timeout("30s").getAsync());
    }

    List<WS.HttpResponse> results = await(F.Promise.waitAll(promises));
    for (WS.HttpResponse response : results) {
        if (!response.success()) {
            logger.debug("Failed accessing one of " + Joiner.on(", ").join(urls));
            return false;
        }
    }

    return true;
}

Но я нашел несколько предостережений:

  • Я получаю исключение на WS.url (url), если рассматриваемый URLплохо разрешается (например, http://a.com/).
  • По крайней мере, при отладке кажется, что вызов getAsync() блоков ... это действительно асинхронно в производстве?Я знаю, что у Play меньше потоков в режиме Dev, но я думал, что вызов даже не начнется в этот момент.
  • Если один из URL-адресов недоступен, я не уверен, как записать неудачный журнал(как получить доступ к URL из объекта WS.HttpResponse)

Итак, я решил использовать синхронизацию HTTP вместо асинхронного.Кажется, работает следующая реализация:

private static boolean checkUrlsAreReachable(String... urls) {
    checkArgument(urls.length > 0);

    List<F.Promise<Boolean>> promises = newArrayList();
    for (final String url : urls) {
        promises.add(new Job<Boolean>(){
            @Override
            public Boolean doJobWithResult() throws Exception {
                try {
                    WS.HttpResponse result = WS.url(url).followRedirects(true)
                        .timeout("30s").get();
                    return result.success();
                } catch (Exception e) {
                    return false;
                }
            }
        }.now());
    }
    F.Promise<List<Boolean>> allResults = F.Promise.waitAll(promises);
    List<Boolean> booleans = await(allResults);
    return Booleans3.and(booleans);
}

Есть ли способ заставить работать асинхронную реализацию?

1 Ответ

0 голосов
/ 07 ноября 2012

установить часть настройки пула заданий в application.conf

# Jobs executor
# ~~~~~~
# Size of the Jobs pool
play.jobs.pool=20

# Execution pool
# ~~~~~
# Default to 1 thread in DEV mode or (nb processors + 1) threads in PROD mode.
# Try to keep a low as possible. 1 thread will serialize all requests (very useful for debugging purpose)
play.pool=5

И просто поместите проверочную часть в задание, такое как CheckingJob, и запустите его, используя

new CheckingJob().now()

это будет асинхронно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...