Первоначально я пытался это сделать:
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);
}
Есть ли способ заставить работать асинхронную реализацию?