The following code pings an NGINX location block on my NGINX server to give you a health check status.
const ping = async () => {
const url = `http://10.10.1.100/status`;
const postData = {
method: 'POST', // *GET, POST, PATCH, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
headers: {
'Content-Type': 'text/plain; charset=ASCII'
},
body: 'PING'
}
try {
let factor = 1;
let timeout = 3000; // ms
let start = (new Date()).getTime();
const request = await fetch(url, postData);
let delta = new Date().getTime() - start;
delta *= (factor || 1);
if(delta > timeout) throw new Error(`PONG > ${timeout}ms. Server down?`);
if(!request.ok) throw new Error(`${request.status} ${request.statusText}`);
const response = await request.text();
if(!response) throw new Error(`${response}`);
document.getElementById('serverPongSpeed').innerText = `${delta.toFixed(0)}ms`;
// Do Something...
console.log(`%c${delta.toFixed(0)}ms ${response}`, "color: #c6ff00"); // Lime A400
} catch (error) {
console.log(error);
}
}
The NGINX location block:
location = /status {
access_log off;
default_type text/plain;
add_header "Access-Control-Allow-Methods" "POST";
add_header "Content-Type" "text/plain";
return 200 "PONG";
}
Right now I run it like this:
setInterval(ping, 3000); // Every 3 seconds
The problem is, during testing, when I turn off NGINX to see what happens the PING doesn't break. It just keeps sending POST requests.
Maybe it's an error I am not catching? Or maybe there is no error because the fetch has a greater timeout? Maybe setting a fetch timeout at 3 seconds would fire something for me to catch..
CodePudding user response:
Below is a revised, complete example of the desired working solution.
The javascript asynch await ping function:
- Ping function set to POST a request to NGINX /status location block.
- Ping function set to timeout at 300ms to indicate possible server down.
- Ping function set to indicate increased network latency using preset thresholds.
- Ping function set to catch network level error and any other unknown error.
- Ping function returns output to Console.
...
// Settings
const settings = {
pingInterval: 1000, // ms
latency: {
factor: 1.0, // Adjust latency to a percentage of its total
high: 99, // ms
moderate: 66, // ms
low: 33, // ms
},
timeout: 300, // ms
consoleLogLimit: 10,
consoleLogCount: 0,
};
const ping = async() => {
const url = `http://10.10.1.100/status`;
const postData = {
method: 'POST', // *GET, POST, PATCH, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
headers: {
'Content-Type': 'text/plain; charset=ASCII'
},
body: 'PING'
}
try {
let startWatch = (new Date()).getTime();
const request = await fetch(url, postData);
let stopWatch = (new Date().getTime() - startWatch) * (settings.latency.factor || 1);
if (!request.ok) throw new Error(`${request.status} ${request.statusText}`);
const response = await request.text();
if (!response) throw new Error(`${response}`);
if (stopWatch >= settings.timeout) {
throw new Error(`PONG > ${settings.timeout}ms. Server down?`, "color: #d500f9"); // purple A400
} else if (stopWatch >= settings.latency.high) {
console.log(`%c${response}: ${stopWatch}ms High Latency`, "color: #ff1744"); // red A400
} else if (stopWatch >= settings.latency.moderate) {
console.log(`%c${response}: ${stopWatch}ms Moderate Latency`, "color: #ffc400"); // amber A400
} else if (stopWatch <= settings.latency.low) {
console.log(`%c${response}: ${stopWatch}ms Low Latency`, "color: #00e676"); // green A400
}
} catch (error) {
// Catch network level error
if (error instanceof TypeError && error.message == 'NetworkError when attempting to fetch resource.') {
console.log(`%cPING: ${settings.timeout}ms timeout. Server down?`, "color: #651fff"); // purple A400
} else {
// Catch any other error
console.log(error);
}
} finally {
settings.consoleLogCount ;
// Prevents browser from getting sluggish
if (settings.consoleLogCount > settings.consoleLogLimit) {
// Reset limit
settings.consoleLogCount = 0;
// Clear console
console.clear();
}
}
}
setInterval(ping, settings.pingInterval);
...
The NGINX server /status location block:
- End point set to accept POST only requests on
/location
end point. - End point access log set to disabled because we don't really need to log this.
- End point set to respond with content type set to text/plain.
- End point set to accept POST requests from any origin.
- End point set to return a Content-Type of text/plain with a text "PONG" response on success.
...
location = /status {
access_log off;
default_type text/plain;
limit_except POST {
deny all;
}
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "POST, OPTIONS" always;
add_header Content-Type "text/plain" always;
return 200 "PONG";
}
CodePudding user response:
you can use ClearInterval() method like this:
var interval = setInterval(ping, 3000);
if(timeoutCounter > 3)
clearInterval(interval)
you need some more code to count the time outs/ errors. something like circuit breaker pattern