@constructive-io/graphql-server 5.33.1 → 5.33.3

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.
@@ -92,17 +92,31 @@ export const createAdmissionControlMiddleware = (options = {}) => {
92
92
  return;
93
93
  }
94
94
  // ─── Per-database concurrency ───────────────────────────────────────────
95
+ // A client that hangs up while queued must neither keep its place in the
96
+ // queue nor be handed the slot when its turn comes: nothing would ever
97
+ // release it. `close` is watched from before the wait, since a listener
98
+ // attached only after `acquire` resolves misses a hang-up during it.
99
+ const gone = new AbortController();
100
+ const onClose = () => gone.abort();
101
+ res.once('close', onClose);
95
102
  let lease;
96
103
  try {
97
104
  lease = await concurrency.acquire(databaseId, {
98
105
  limit: protection.maxConcurrentRequests,
99
- queueWaitMs: protection.maxQueueWaitMs
106
+ queueWaitMs: protection.maxQueueWaitMs,
107
+ signal: gone.signal
100
108
  });
101
109
  }
102
110
  catch (e) {
111
+ res.off('close', onClose);
103
112
  next(e);
104
113
  return;
105
114
  }
115
+ res.off('close', onClose);
116
+ if (gone.signal.aborted) {
117
+ lease.release();
118
+ return;
119
+ }
106
120
  if (!lease.granted) {
107
121
  log.warn(`[admission] concurrency refused: database=${databaseId} ` +
108
122
  `limit=${protection.maxConcurrentRequests} reason=${lease.refusal} waited=${lease.queuedMs}ms`);
@@ -95,17 +95,31 @@ const createAdmissionControlMiddleware = (options = {}) => {
95
95
  return;
96
96
  }
97
97
  // ─── Per-database concurrency ───────────────────────────────────────────
98
+ // A client that hangs up while queued must neither keep its place in the
99
+ // queue nor be handed the slot when its turn comes: nothing would ever
100
+ // release it. `close` is watched from before the wait, since a listener
101
+ // attached only after `acquire` resolves misses a hang-up during it.
102
+ const gone = new AbortController();
103
+ const onClose = () => gone.abort();
104
+ res.once('close', onClose);
98
105
  let lease;
99
106
  try {
100
107
  lease = await concurrency.acquire(databaseId, {
101
108
  limit: protection.maxConcurrentRequests,
102
- queueWaitMs: protection.maxQueueWaitMs
109
+ queueWaitMs: protection.maxQueueWaitMs,
110
+ signal: gone.signal
103
111
  });
104
112
  }
105
113
  catch (e) {
114
+ res.off('close', onClose);
106
115
  next(e);
107
116
  return;
108
117
  }
118
+ res.off('close', onClose);
119
+ if (gone.signal.aborted) {
120
+ lease.release();
121
+ return;
122
+ }
109
123
  if (!lease.granted) {
110
124
  log.warn(`[admission] concurrency refused: database=${databaseId} ` +
111
125
  `limit=${protection.maxConcurrentRequests} reason=${lease.refusal} waited=${lease.queuedMs}ms`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-server",
3
- "version": "5.33.1",
3
+ "version": "5.33.3",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "Constructive GraphQL Server",
6
6
  "main": "index.js",
@@ -43,7 +43,7 @@
43
43
  "@agentic-kit/ollama": "2.16.0",
44
44
  "@constructive-io/csrf": "^0.31.0",
45
45
  "@constructive-io/errors": "^0.25.0",
46
- "@constructive-io/express-context": "^0.35.1",
46
+ "@constructive-io/express-context": "^0.35.2",
47
47
  "@constructive-io/graphql-env": "^3.37.2",
48
48
  "@constructive-io/graphql-types": "^3.36.1",
49
49
  "@constructive-io/llm-env": "^0.16.0",
@@ -70,9 +70,9 @@
70
70
  "graphile-config": "1.1.0",
71
71
  "graphile-function-bindings": "^1.19.0",
72
72
  "graphile-plugin-utils": "^1.14.1",
73
- "graphile-presigned-url-plugin": "^1.23.3",
73
+ "graphile-presigned-url-plugin": "^1.23.4",
74
74
  "graphile-scoped-introspection": "^0.6.0",
75
- "graphile-settings": "^6.28.0",
75
+ "graphile-settings": "^6.28.2",
76
76
  "graphile-utils": "5.0.3",
77
77
  "graphql": "16.13.0",
78
78
  "graphql-upload": "^13.0.0",
@@ -100,5 +100,5 @@
100
100
  "supertest": "^7.2.2",
101
101
  "ts-node": "^10.9.2"
102
102
  },
103
- "gitHead": "69c7d68237a248bf5923dd6e3e3e5d73674c4050"
103
+ "gitHead": "f186681da756546c8dad36bd690d525df9b68af3"
104
104
  }