Last active
February 26, 2024 01:04
-
-
Save kofigumbs/2b3a4eb856b4bed406a04f6ecea22e99 to your computer and use it in GitHub Desktop.
Zero-downtime Node deploys using parent process proxy, early exploration for https://kofi.sexy/blog/zero-downtime-render-disk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { spawn } from 'child_process' | |
import { createServer, request } from 'http' | |
import pidtree from 'pidtree' | |
const deployCommand = ['npm', ['start']] | |
const deployWait = 30 * 1000 | |
const deploySecretPath = '/~deploy-01HPZ2ACGJSJJ0NGX9MT1RYRDB' | |
let server = startServer(8001) | |
const proxy = createServer((clientRequest, clientResponse) => { | |
if (clientRequest.url === deploySecretPath) { | |
restartServer() | |
clientResponse.writeHead(202).end() | |
return | |
} | |
const forward = { | |
method: clientRequest.method, | |
headers: clientRequest.headers, | |
path: clientRequest.url, | |
port: server.PORT, | |
} | |
const serverRequest = request(forward, (serverResponse) => { | |
clientResponse.writeHead(serverResponse.statusCode, serverResponse.headers) | |
serverResponse.pipe(clientResponse, { end: true }) | |
}) | |
serverRequest.on('error', (error) => { | |
handleError(error) | |
clientResponse.writeHead(502).end() | |
}) | |
clientRequest.pipe(serverRequest, { end: true }) | |
}) | |
function startServer(PORT) { | |
return { | |
process: spawn(...deployCommand, { stdio: 'inherit', env: { ...process.env, PORT } }).on('error', console.error), | |
PORT, | |
} | |
} | |
function restartServer() { | |
if (server.stopping) | |
return | |
server.stopping = true | |
const oldServer = server | |
const newServer = startServer(server.PORT + 1) | |
setTimeout( | |
() => { | |
server = newServer | |
pidtree(oldServer.process.pid, { root: true }).then((pids) => pids.map((pid) => process.kill(pid)), console.error) | |
}, | |
deployWait, | |
) | |
} | |
proxy.listen(10000) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment