Search code examples
javascriptreactjsdeferred-result

How to understand when a ReadbleStream is closed from the server [Using DeferredResult on Server side]?


I have implemented the a polling using DeferredResult in Spring and on the client side I handle the data I receive form the server.

In the client side I have a simple page with plain javascript:

// start polling (ignore placeholder)
function polling() {
    console.log("call with fetch");
    fetch('%@[urlPolling]')
     .then(function(response) {
           console.log(response);
           return response.text();
         }).then(function(data) {
           console.log(data); // this will be a string
           var dataJson = JSON.parse(data);
           if (dataJson.status == "OK" || dataJson.status == "KO") {
                addLoaderEffect();
                console.log("completato");
                sendPollingResult();
            } else if (dataJson.status == "ERROR") {
                console.log("error from server, executing polling again");
                setTimeout(polling, 3000);
            }
         })
     .catch((error) => {
       console.error('Error:', error);
       setTimeout(polling, 3000);
     });
}

polling();

There is a way to understand when the connection with the server is closed? For example during a release the instance will be replaced and the client will wait for an answer indefinitely. There is a way to handle such scenario?


Solution

  • On the backend side we could set a result to the deferred result during the undeployment of our application so that the client receive the "ERROR" state and it can repeat the request. [I'm assuming the release is blue green]

    @PreDestroy
    public void preDestroy() {
            try {
                LOGGER.info("Undeploy LongPollingManager");
                // each transaction receive "ERROR"
                resultMap.forEach((key, value) -> {
                    setupPollingResponse(OPERATION_STATUS_UNDEPLOY, key, resultMap);
                });
            } catch (Exception e) {
                LOGGER.info("Exception during Undeploy LongPollingManager", e);
            }
        }
    
    private void setupPollingResponse(String operationStatus, String operationId, ConcurrentHashMap<String, ScaOperationStatusDeferredResult> resultMap) {
            ScaOperationStatusDeferredResult retrievedResult = resultMap.remove(operationId);
            retrievedResult.setResult(getSuccessResult(operationStatus));
    }
    
    

    resultMap is a map that contains all the long polling operations.