Vertx client is taking time to check for failure

148 Views Asked by At

I have a requirement where I am connecting one microservice to other microservice via Vertx client. In the code I am checking if another microservice is down then on failure it should create some JsonObject with solrError as key and failure message as value. If there is a solr error I mean if other microservice is down which is calling solr via load balancing then it should throw some error response. But Vertx client is taking some time to check on failure and when condition is checked that time there is no solrError in jsonobject as Vertx client is taking some time to check for failure so condition fails and resp is coming as null. In order to avoid this what can be done so that Vertx client fails before the condition to check for solrError and returns Internal server error response?

Below is the code :

 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()
                    && CollectionUtils.isNotEmpty(solrOutput.getResponse().getDocs())) {
                docs.addAll(solrOutput.getResponse().getDocs());
                                    uniDocList  = Uni.createFrom().item(docs);
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    });
    
    if(null!=resp && 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 && "https".equals(url.getProtocol())) {
        port = 443;
    }
    if (port == -1 && "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

There are 1 best solutions below

0
On

I have not used the Vertx client but assume its reactive and non-blocking. Assuming this is the case, your code seems to be mixing imperative and reactive constructs. The subscribe in the first line is reactive and the lambda you provide will be called when the server responds to the client request. However, after the subscribe, you have imperative code which runs before the lambda even has a chance to be called so your checks and access to the "resp" object will never be a result of what happened in the lambda itself.

You need to move all the code into the lambda or at least make subsequent code chain onto the result of the subscribe.