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?
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.