@jsenv/server 15.1.7 → 15.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +6 -6
  2. package/src/start_server.js +20 -19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/server",
3
- "version": "15.1.7",
3
+ "version": "15.2.0",
4
4
  "description": "Write your Node.js server using pure functions",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -34,11 +34,11 @@
34
34
  "test": "node --conditions=development ./scripts/test.mjs"
35
35
  },
36
36
  "dependencies": {
37
- "@jsenv/abort": "4.2.4",
38
- "@jsenv/log": "3.4.3",
39
- "@jsenv/url-meta": "8.2.0",
40
- "@jsenv/utils": "2.0.1",
41
- "ws": "8.14.2"
37
+ "@jsenv/abort": "4.3.0",
38
+ "@jsenv/log": "3.5.1",
39
+ "@jsenv/url-meta": "8.4.0",
40
+ "@jsenv/utils": "2.1.1",
41
+ "ws": "8.16.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@jsenv/fetch": "../fetch/",
@@ -1,11 +1,7 @@
1
1
  import { isIP } from "node:net";
2
2
  import cluster from "node:cluster";
3
3
  import { createDetailedMessage, createLogger } from "@jsenv/log";
4
- import {
5
- Abort,
6
- raceProcessTeardownEvents,
7
- createCallbackListNotifiedOnce,
8
- } from "@jsenv/abort";
4
+ import { Abort, raceProcessTeardownEvents } from "@jsenv/abort";
9
5
  import { memoize } from "@jsenv/utils/src/memoize/memoize.js";
10
6
 
11
7
  import { createServiceController } from "./service_controller.js";
@@ -156,7 +152,7 @@ export const startServer = async ({
156
152
  let status = "starting";
157
153
  let nodeServer;
158
154
  const startServerOperation = Abort.startOperation();
159
- const stopCallbackList = createCallbackListNotifiedOnce();
155
+ const stopCallbackSet = new Set();
160
156
  const serverOrigins = {
161
157
  local: "", // favors hostname when possible
162
158
  };
@@ -280,10 +276,10 @@ export const startServer = async ({
280
276
  // (otherwise an AbortError is thrown to the code calling "startServer")
281
277
  // we can proceed to create a stop function to stop it gacefully
282
278
  // and add a request handler
283
- stopCallbackList.add(({ reason }) => {
279
+ stopCallbackSet.add(({ reason }) => {
284
280
  logger.info(`${serverName} stopping server (reason: ${reason})`);
285
281
  });
286
- stopCallbackList.add(async () => {
282
+ stopCallbackSet.add(async () => {
287
283
  await stopListening(nodeServer);
288
284
  });
289
285
  let stoppedResolve;
@@ -292,7 +288,12 @@ export const startServer = async ({
292
288
  });
293
289
  const stop = memoize(async (reason = STOP_REASON_NOT_SPECIFIED) => {
294
290
  status = "stopping";
295
- await Promise.all(stopCallbackList.notify({ reason }));
291
+ const promises = [];
292
+ for (const stopCallback of stopCallbackSet) {
293
+ promises.push(stopCallback({ reason }));
294
+ }
295
+ stopCallbackSet.clear();
296
+ await Promise.all(promises);
296
297
  serviceController.callHooks("serverStopped", { reason });
297
298
  status = "stopped";
298
299
  stoppedResolve(reason);
@@ -304,7 +305,7 @@ export const startServer = async ({
304
305
  stop(PROCESS_TEARDOWN_EVENTS_MAP[winner.name]);
305
306
  },
306
307
  );
307
- stopCallbackList.add(cancelProcessTeardownRace);
308
+ stopCallbackSet.add(cancelProcessTeardownRace);
308
309
 
309
310
  const onError = (error) => {
310
311
  if (status === "stopping" && error.code === "ECONNRESET") {
@@ -319,19 +320,19 @@ export const startServer = async ({
319
320
  nodeServer,
320
321
  onError,
321
322
  );
322
- stopCallbackList.add(removeConnectionErrorListener);
323
+ stopCallbackSet.add(removeConnectionErrorListener);
323
324
 
324
325
  const connectionsTracker = trackServerPendingConnections(nodeServer, {
325
326
  http2,
326
327
  });
327
328
  // opened connection must be shutdown before the close event is emitted
328
- stopCallbackList.add(connectionsTracker.stop);
329
+ stopCallbackSet.add(connectionsTracker.stop);
329
330
 
330
331
  const pendingRequestsTracker = trackServerPendingRequests(nodeServer, {
331
332
  http2,
332
333
  });
333
334
  // ensure pending requests got a response from the server
334
- stopCallbackList.add((reason) => {
335
+ stopCallbackSet.add((reason) => {
335
336
  pendingRequestsTracker.stop({
336
337
  status: reason === STOP_REASON_INTERNAL_ERROR ? 500 : 503,
337
338
  reason,
@@ -371,13 +372,13 @@ export const startServer = async ({
371
372
  };
372
373
  });
373
374
  receiveRequestOperation.addAbortSource((abort) => {
374
- return stopCallbackList.add(abort);
375
+ return stopCallbackSet.add(abort);
375
376
  });
376
377
 
377
378
  const sendResponseOperation = Abort.startOperation();
378
379
  sendResponseOperation.addAbortSignal(receiveRequestOperation.signal);
379
380
  sendResponseOperation.addAbortSource((abort) => {
380
- return stopCallbackList.add(abort);
381
+ return stopCallbackSet.add(abort);
381
382
  });
382
383
 
383
384
  const request = fromNodeRequest(nodeRequest, {
@@ -930,7 +931,7 @@ export const startServer = async ({
930
931
  };
931
932
  const removeRequestListener = listenRequest(nodeServer, requestCallback);
932
933
  // ensure we don't try to handle new requests while server is stopping
933
- stopCallbackList.add(removeRequestListener);
934
+ stopCallbackSet.add(removeRequestListener);
934
935
  }
935
936
 
936
937
  websocket: {
@@ -983,8 +984,8 @@ export const startServer = async ({
983
984
  "upgrade",
984
985
  upgradeCallback,
985
986
  );
986
- stopCallbackList.add(removeUpgradeCallback);
987
- stopCallbackList.add(() => {
987
+ stopCallbackSet.add(removeUpgradeCallback);
988
+ stopCallbackSet.add(() => {
988
989
  websocketClients.forEach((websocketClient) => {
989
990
  websocketClient.close();
990
991
  });
@@ -1017,7 +1018,7 @@ export const startServer = async ({
1017
1018
  addEffect: (callback) => {
1018
1019
  const cleanup = callback();
1019
1020
  if (typeof cleanup === "function") {
1020
- stopCallbackList.add(cleanup);
1021
+ stopCallbackSet.add(cleanup);
1021
1022
  }
1022
1023
  },
1023
1024
  });