day-5.mjs
December 29, 2021 ยท View on GitHub
/////////////////////////////////////////////////////////////////////////////// // Day 5 - Are we done yet? // // #region problem // /////////////////////////////////////////////////////////////////////////////// // Make a middleware that saves a timestamp from req.expires so that when // // calling an async function keepGoing it resolves as long as Date.now() is // // less than the expires time. Otherwise it throws an Error. // ///////////////////////////////////////////////////////////////////////////////
/**
- Save req.auth so that using
read()from insidenext()returns req.auth - be wary of multiple concurrent calls to
save() - @param {import('http').IncomingMessage} req
- @param {import('http').ServerResponse} res
- @param {(err?: Error) => void} next
- @returns {void} */ function save(req, res, next) { // ... }
/**
- DO NOT ADD PARAMETERS
- @returns {void} */ function keepGoing() { // ... }
/////////////////////////////////////////////////////////////////////////////// // #endregion problem // ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// // Test - Leave code after this alone // // #region test // ///////////////////////////////////////////////////////////////////////////////
import {once} from 'node:events'; import timers from 'node:timers/promises';
import http from 'node:http';
const pending = []; const server = http.createServer((req, res) => { console.log('HTTP REQ', req.method, req.url) const expires = Date.now() + 100; req.expires = expires; save(req, res, async () => { let cont = new Promise((f, r) => { pending.push(() => f()); if (pending.length === 2) { process.exitCode = 0; for (const end of pending) { end(); } } }); await cont; try { // will fail for first request since second is started after // first expires await keepGoing(); if (req.url === '/1') { res.writeHead(500); res.end('/1 should be expired and throw an error'); } } catch (e) { if (req.url !== '/1') { res.writeHead(500); res.end('only /1 should be expired and throw an error'); throw e; } } res.end(); }); }).listen(0, '127.0.0.1'); process.exitCode = 1; server.unref();
await once(server, 'listening');
const url = http://127.0.0.1:${server.address().port}/;
const req1 = http.get(url + '1').end();
await timers.setTimeout(150);
const req2 = http.get(url + '2').end();
/////////////////////////////////////////////////////////////////////////////// // #endregion test // ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// // Hints - Encoded in ROT13 encoded // // #region hints // /////////////////////////////////////////////////////////////////////////////// // // // Fvzcyr: lbh arrq fbzr qngn fgber gb genpx gur nflap pbagrkg. // // // /////////////////////////////////////////////////////////////////////////////// // #endregion hints // ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// // Use Cases // // #region uses // /////////////////////////////////////////////////////////////////////////////// // // // Sometimes APIs cannot have parameters/data added to them due to being 3rd // // party libraries, or requiring a breaking change. Having implicit access // // to contextual data allows working around this. // // // /////////////////////////////////////////////////////////////////////////////// // #endregion uses // ///////////////////////////////////////////////////////////////////////////////