Skip to content

Instantly share code, notes, and snippets.

@ardeshireshghi
Last active August 14, 2020 16:56
Show Gist options
  • Save ardeshireshghi/b0b9e3ce37f42a59dd6f12ddfef81386 to your computer and use it in GitHub Desktop.
Save ardeshireshghi/b0b9e3ce37f42a59dd6f12ddfef81386 to your computer and use it in GitHub Desktop.
const SERVICE_DISCOVERY_PORT = 3600;
function discoverService(name) {
const client = new net.Socket();
return new Promise(resolve => {
client.connect(SERVICE_DISCOVERY_PORT, () => {
client.write(`resolve ${name}`);
});
client.on('data', (address) => {
client.destroy();
resolve(address);
});
});
}
function registerService(name, address) {
const client = new net.Socket();
return new Promise(resolve => {
client.connect(SERVICE_DISCOVERY_PORT, () => {
client.write(`register ${name},${address}`);
client.on('data', () => {
client.destroy();
resolve();
});
});
});
exports.register = registerService;
exports.discover = discoverService;
const net = require('net');
const fs = require('fs');
const { promisify } = require('util');
const writeFile = promisify(fs.writeFile);
const SERVICE_PORT = 3600;
const getRegisteredServicesMap = () => {
if (!fs.existsSync('./service-catalogue.json')) {
return new Map();
}
const rawCatalogueData = fs.readFileSync('./service-catalogue.json', 'utf-8');
const servicesData = JSON.parse(rawCatalogueData ? rawCatalogueData : "{}");
return new Map(Object.entries(servicesData));
};
const registeredServices = getRegisteredServicesMap();
const persistToCatalogue = async (servicesMap) => {
const servicesMapToJsonPayload = JSON.stringify(Object.fromEntries(servicesMap));
await writeFile('./service-catalogue.json', servicesMapToJsonPayload);
};
const register = async (commandParams) => {
try {
const [ serviceName, url = null ] = commandParams.split(',');
registeredServices.set(serviceName, url);
await persistToCatalogue(registeredServices);
} catch (err) {
throw new Error(`Error registering the service: ${err.message}`);
}
};
const resolve = (commandParams) => {
try {
const [ serviceName ] = commandParams.split(',');
if (registeredServices.has(serviceName)) {
return registeredServices.get(serviceName);
}
} catch(err) {
throw new Error(`Error discovering the service: ${err.message}`);
}
};
const commands = {
register,
resolve
};
const server = net.createServer((socket) => {
socket.on('data', async (data) => {
try {
const message = data.toString().trim();
if (!message) {
throw new Error('No command is received');
}
const [commandName, commandParams] = message.split(' ');
const executor = commandName in commands ? commands[commandName] : null;
if (!executor) {
throw new Error('Invalid command');
}
const result = await executor(commandParams);
console.log('[Service discovery]: Command "%s" with params "%s" served successfully', commandName, commandParams);
socket.end(result);
} catch (err) {
socket.end(err.message);
};
});
}).on('error', (err) => {
console.error(err.stack);
// Handle errors here.
throw err;
});
// Grab an arbitrary unused port.
server.listen(SERVICE_PORT, () => {
console.log('Service discovery service started', server.address());
});
// Register new service using bash
// echo "register nice,179.200.10.55" | nc localhost 3600
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment