devinov
devinov

Reputation: 567

How to synchronously check for TCP connectivity in Node.js?

The application needs to consistently check if any of multiple servers is available. I want this to be done in the background periodically and just check the status of the last check whenever I need to know connectivity status. Being able to use a socket synchronously like you can in other languages would be helpful so that my periodic async func isn't running a bunch of its own async function and because in my case, any of the servers being successful is good enough for a success status. The other ones shouldn't be checked anymore and the other ones shouldn't be setting the overall status as bad just because one of the async tasks was bad.

Current Async situation

function checkServersPeriodically() {
    var servers = [{'host': 'localhost', port: 80}, {'host': 'localhost', port: 95}];
    for (var i = 0; i < servers.length; i++) {
        someAyncFunction(servers[i].host, servers[i].port, (err) => {
             //could have two async checks with different outcomes
             if (err) bad();
             else good();
        });
    }
}

What I was looking for (similar to if I were to do use some sort of file system check I'd just use fs.readSync)

 function checkServersPeriodically() {
    var servers = [{'host': 'localhost', port: 80}, {'host': 'localhost', port: 95}];
    for (var i = 0; i < servers.length; i++) {
        try {
            someSyncFunction(servers[i].host, servers[i].port);
            good();
            return; // Skips the other checks
        } 
     }
     bad();
 }

Upvotes: 0

Views: 549

Answers (1)

Estus Flask
Estus Flask

Reputation: 223114

This can be conveniently handled with async..await which provides synchronous-like control flow for promises:

const { promisify } = require('util');
const somePromiseFunction = promisify(someAyncFunction);

async function checkServersPeriodically() {
    var servers = [{'host': 'localhost', port: 80}, {'host': 'localhost', port: 95}];
    for (var i = 0; i < servers.length; i++) {
        try {
            await somePromiseFunction(servers[i].host, servers[i].port);
            good();
            return; // Skips the other checks
        } catch (err) {}
     }
     bad();
 }

checkServersPeriodically returns a promise. There's a chance that callbacks like good and bad` are remnants of callback-based API, and a success or a failure should be handled in caller function instead:

async function checkServersPeriodically() {
    var servers = [{'host': 'localhost', port: 80}, {'host': 'localhost', port: 95}];
    for (var i = 0; i < servers.length; i++) {
        try {
            await somePromiseFunction(servers[i].host, servers[i].port);
            return; // Skips the other checks
        } catch (err) {}
     }
     throw new Error('no servers');
 }

checkServersPeriodically().then(good, bad);

Upvotes: 1

Related Questions