Синхронизировать ответ на запрос в Java - PullRequest
0 голосов
/ 28 октября 2019

У меня есть некоторые сервисы, которые предоставляют информацию в разное время, но я бы хотел, чтобы некоторые сервисы предоставляли все ответы одновременно, несмотря на то, что это разные сервисы.

Я использую java 11 с весенней загрузкой и использую apiОтдых Я оставлю ниже пример одной из служб

@GetMapping(value = "/caract/opcoes/acoes/disponiveis")
public ResponseEntity<List<GroupByData>> getDatasCaractOpcoesAcoesDisponiveis() {
    List<GroupByData> result = caractOpcoesAcoesServico.findGroupByIdentityRptDt();
    if (result.isEmpty()) {
        return new ResponseEntity<List<GroupByData>>(HttpStatus.NO_CONTENT);
    }
    return new ResponseEntity<List<GroupByData>>(result, HttpStatus.OK);
} 

Как я могу освободить ответ на несколько запросов, которые были выпущены в разное время, только после того, как все будут готовы?

1 Ответ

0 голосов
/ 02 ноября 2019

Есть 2 способа сделать это. Сначала я объясню хороший способ, который является реактивным и веб-потоком.

@GetMapping(value = "/anothertest")
public Mono<String> rest() {
    log.info("request number " + reqCounter++);
    CompletableFuture<String> stringCompletableFuture = sendRequestWithJavaHttpClient().thenApply(x -> "test: " + x);
    Duration between = Duration.between(
            LocalTime.now(),
            LocalTime.parse("14:01:00")// I am assuming there is a time we send data back 
    );
    return Mono.first(Mono.delay(between)).then(Mono.fromFuture(stringCompletableFuture));
}

private CompletableFuture<String> sendRequestWithJavaHttpClient() {
    return CompletableFuture.supplyAsync(() -> {
        // do some logic here
        return "hello world.";
    });
}

Как мы говорим первому моно, чтобы отложить ответ, он будет ждать, пока придет время, и выполнит вызов функции после. Это хороший способ, потому что при этом способе нет блокировки ответа. все клиенты должны будут ждать. вам нужно будет использовать пружину.

Второй и не крутой способ - заблокировать нить. этот использует пружинный MVC

@GetMapping(value = "/caract/opcoes/acoes/disponiveis*")
public ResponseEntity<Object> getDatasCaractOpcoesAcoesDisponiveis() throws Exception {
    log.info("request number " + reqCounter++);
    Duration between = Duration.between(
            LocalTime.now(),
            LocalTime.parse("14:10:00")
    );
    log.info("will sleep "+between.toMillis());
    Thread.sleep(between.toMillis());
    return new ResponseEntity<Object>("hello world", HttpStatus.OK);
}

Это будет блокировать поток сервера, пока не наступит время. Проблема в том, что счетчик потоков Tomcat. значение по умолчанию равно 200, поэтому ваше приложение может иметь не более 200 запросов, и после этого tomcat больше не может принимать соединение. Вы можете увеличить его, изменив server.tomcat.max-threads = 500 в application.properties

. Вы можете найти пример кода здесь https://github.com/ozkanpakdil/spring-examples/tree/master/response-wait-methods

Если вы спросите мое мнение об этих двухпути с точки зрения дизайна не очень приятные, потому что клиентам не стоит ждать. Я бы пошел с ответом NOK, пока не придет время. и если время хорошее, просто ответь реальным результатом. таким образом, клиентская сторона может запрашивать столько, сколько они хотят без нагрузки. и на стороне сервера не будет никакой нагрузки, потому что ничто не заблокировано.

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