Клиенту Vertx требуется время для проверки на наличие сбоя

#java #redhat #vert.x #quarkus #vertx-httpclient

Вопрос:

У меня есть требование, когда я подключаю один микросервис к другому микросервису через клиент Vertx. В коде, который я проверяю, отключен ли другой микросервис, при сбое он должен создать некоторый JSONObject с solrError в качестве ключа и сообщением об ошибке в качестве значения. Если есть ошибка solr, я имею в виду, что если не работает другой микросервис, который вызывает solr через балансировку нагрузки, то он должен выдать какой-то ответ на ошибку. Но клиенту Vertx требуется некоторое время, чтобы проверить сбой, и когда условие проверено, в jsonobject нет ошибки, так как клиенту Vertx требуется некоторое время для проверки на сбой, поэтому условие не выполняется, и соответственно значение равно нулю. Чтобы избежать этого, что можно сделать, чтобы клиент Vertx вышел из строя до выполнения условия проверки на ошибку solrError и вернул ответ на внутреннюю ошибку сервера?

Ниже приведен код :

  solrQueryService.executeQuery(query).subscribe().with(jsonObject -> {
        ObjectMapper objMapper = new ObjectMapper();
        SolrOutput solrOutput = new SolrOutput();
        List<Doc> docs = new ArrayList<>();
        try {
            if(null != jsonObject.getMap().get("solrError")){
             resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                        .entity(new BaseException(
                                exceptionService.processSolrDownError(request.header.referenceId))
                                        .getResponse()).build();
            }
            solrOutput = objMapper.readValue(jsonObject.toString(), SolrOutput.class);
            if (null != solrOutput.getResponse()
                    amp;amp; CollectionUtils.isNotEmpty(solrOutput.getResponse().getDocs())) {
                docs.addAll(solrOutput.getResponse().getDocs());
                                    uniDocList  = Uni.createFrom().item(docs);
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    });
    
    if(null!=resp amp;amp; resp.getStatus() !=200) {
        return resp ;
    }
    
    SolrQueryService is preparing query and send out URL and query to Vertx web client as below :
    
    public Uni<JsonObject> search(URL url, SolrQuery query,Integer timeout) {
    int port = url.getPort();
    if (port == -1 amp;amp; "https".equals(url.getProtocol())) {
        port = 443;
    }
    if (port == -1 amp;amp; "http".equals(url.getProtocol())) {
        port = 80;
    }
    HttpRequest<Buffer> request = client.post(port, url.getHost(), url.getPath()).timeout(timeout);
    return request.sendJson(query).map(resp -> {
        return resp.bodyAsJsonObject();
    }).onFailure().recoverWithUni(f -> {
        return Uni.createFrom().item(new JsonObject().put("solrError", f.getMessage()));
    });

}
 

Ответ №1:

Я не использовал клиент Vertx, но предполагаю, что он реагирует и не блокируется. Предполагая, что это так, ваш код, похоже, смешивает императивные и реактивные конструкции. Подписка в первой строке является реактивной, и лямбда, которую вы предоставляете, будет вызвана, когда сервер ответит на запрос клиента. Однако после подписки у вас есть императивный код, который запускается еще до того, как лямбда-код будет вызван, поэтому ваши проверки и доступ к объекту «resp» никогда не будут результатом того, что произошло в самой лямбде.

Вам нужно переместить весь код в лямбду или, по крайней мере, создать последующую цепочку кода в результате подписки.