Ghost/ghost/bootstrap-socket/lib/bootstrap-socket.js
Hannah Wolfe a01d44fa6a Refactored bootstrap-socket API for testability
- this makes it much easier to stub this behaviour in tests
- also makes more sense
2020-08-09 17:15:46 +01:00

86 lines
2.4 KiB
JavaScript

module.exports.connectAndSend = (socketAddress, logging, message) => {
// Very basic guard against bad calls
if (!socketAddress || !socketAddress.host || !socketAddress.port || !logging || !logging.info || !logging.warn || !message) {
return Promise.resolve();
}
const net = require('net');
const client = new net.Socket();
return new Promise((resolve) => {
const connect = (options = {}) => {
let wasResolved = false;
const waitTimeout = setTimeout(() => {
logging.info('Bootstrap socket timed out.');
if (!client.destroyed) {
client.destroy();
}
if (wasResolved) {
return;
}
wasResolved = true;
resolve();
}, 1000 * 5);
client.connect(socketAddress.port, socketAddress.host, () => {
if (waitTimeout) {
clearTimeout(waitTimeout);
}
client.write(JSON.stringify(message));
if (wasResolved) {
return;
}
wasResolved = true;
resolve();
});
client.on('close', () => {
logging.info('Bootstrap client was closed.');
if (waitTimeout) {
clearTimeout(waitTimeout);
}
});
client.on('error', (err) => {
logging.warn(`Can't connect to the bootstrap socket (${socketAddress.host} ${socketAddress.port}) ${err.code}.`);
client.removeAllListeners();
if (waitTimeout) {
clearTimeout(waitTimeout);
}
if (options.tries < 3) {
logging.warn(`Tries: ${options.tries}`);
// retry
logging.warn('Retrying...');
options.tries = options.tries + 1;
const retryTimeout = setTimeout(() => {
clearTimeout(retryTimeout);
connect(options);
}, 150);
} else {
if (wasResolved) {
return;
}
wasResolved = true;
resolve();
}
});
};
connect({tries: 0});
});
};