Skip to content

Instantly share code, notes, and snippets.

@ncwhale
Created October 4, 2024 15:03
Show Gist options
  • Save ncwhale/db3f389ea35b46e561919519ac32b727 to your computer and use it in GitHub Desktop.
Save ncwhale/db3f389ea35b46e561919519ac32b727 to your computer and use it in GitHub Desktop.
// IMPORTANT: THIS SCRIPT ONLY WORKS IN SYSTEM WHICH SUPPORT UNIX SOCKET!
import fs from 'node:fs'
import http from 'node:http'
import path from 'node:path'
async function lock_server(lock_service_path) {
const server = http.createServer((req, res) => { res.end("ok") })
// make sure this server doesn't keep the process running
server.unref()
server.on('error', function (e) {
if (e.code === "EADDRINUSE") {
// Try to comminute with the server, if it did not answer, we continure by remove the socket and re-create it.
// Are U OK?
const clientRequest = http.request({
socketPath: lock_service_path,
path: '/',
method: 'GET',
timeout: 100, // Should be very short, we are in the same host.
}, (res) => {
res.on('data', (data) => {
console.log(data.toString())
// Exit process when duplicate server is running.
console.log("Sentinel server already running - can't run more than one instance")
process.exit(0)
})
res.on('error', async (e) => {
// So this server is failed, remove the socket file and retry listen.
await fs.promises.unlink(lock_service_path)
server.listen(lock_service_path, () => {
console.log(`Sentinel server restart listening on ${lock_service_path}`)
})
})
})
clientRequest.on('error', (e) => {
console.log(e)
// So this server is failed, remove the socket file and retry listen.
fs.unlinkSync(lock_service_path)
server.listen(lock_service_path, () => {
console.log(`Sentinel server restart listening on ${lock_service_path}`)
})
})
clientRequest.end()
} else {
console.log(e)
}
})
server.listen(lock_service_path, () => {
console.log(`Sentinel server listening on ${lock_service_path}`)
})
return server
}
// Example usage:
await lock_server(path.join('.', '.lock_service'))
// Just do a nap.
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
await sleep(10*1000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment