Skip to content

Commit

Permalink
basic typescript conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
glasser committed Jul 16, 2021
1 parent a6f3187 commit ad25463
Showing 1 changed file with 37 additions and 31 deletions.
68 changes: 37 additions & 31 deletions packages/apollo-server/src/stoppable.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use strict';
// FIXME license, credits

const https = require('https');
import http from 'http';
import https from 'https';
import type { Socket } from 'net';

module.exports = (server, grace) => {
grace = typeof grace === 'undefined' ? Infinity : grace;
const reqsPerSocket = new Map();
export function stoppable(server: http.Server, grace?: number) {
const realGrace = typeof grace === 'undefined' ? Infinity : grace;
const reqsPerSocket = new Map<Socket, number>();
let stopped = false;
let gracefully = true;

Expand All @@ -15,51 +17,55 @@ module.exports = (server, grace) => {
}

server.on('request', onRequest);
server.stop = stop;
server._pendingSockets = reqsPerSocket;
// FIXME make Promisey
const stop = (
callback: (e: Error | undefined, gracefully: Boolean) => void,
) => {
// allow request handlers to update state before we act on that state
setImmediate(() => {
stopped = true;
if (realGrace < Infinity) {
// FIXME don't do unref
setTimeout(destroyAll, realGrace).unref();
}
server.close((e) => {
if (callback) {
callback(e, gracefully);
}
});
reqsPerSocket.forEach(endIfIdle);
});
};

// FIXME return function instead of augmenting
(server as any).stop = stop;
return server;

function onConnection(socket) {
function onConnection(socket: Socket) {
reqsPerSocket.set(socket, 0);
socket.once('close', () => reqsPerSocket.delete(socket));
}

function onRequest(req, res) {
reqsPerSocket.set(req.socket, reqsPerSocket.get(req.socket) + 1);
function onRequest(req: http.IncomingMessage, res: http.ServerResponse) {
reqsPerSocket.set(req.socket, (reqsPerSocket.get(req.socket) ?? 0) + 1);
res.once('finish', () => {
const pending = reqsPerSocket.get(req.socket) - 1;
const pending = (reqsPerSocket.get(req.socket) ?? 0) - 1;
reqsPerSocket.set(req.socket, pending);
if (stopped && pending === 0) {
req.socket.end();
}
});
}

function stop(callback) {
// allow request handlers to update state before we act on that state
setImmediate(() => {
stopped = true;
if (grace < Infinity) {
setTimeout(destroyAll, grace).unref();
}
server.close((e) => {
if (callback) {
callback(e, gracefully);
}
});
reqsPerSocket.forEach(endIfIdle);
});
}

function endIfIdle(requests, socket) {
function endIfIdle(requests: number, socket: Socket) {
if (requests === 0) socket.end();
}

function destroyAll() {
gracefully = false;
reqsPerSocket.forEach((reqs, socket) => socket.end());
reqsPerSocket.forEach((_, socket) => socket.end());
setImmediate(() => {
reqsPerSocket.forEach((reqs, socket) => socket.destroy());
reqsPerSocket.forEach((_, socket) => socket.destroy());
});
}
};
}

0 comments on commit ad25463

Please sign in to comment.