allserver 2.5.0 → 2.6.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allserver",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "Multi-protocol simple RPC server and [optional] client. Boilerplate-less. Opinionated. Minimalistic. DX-first.",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -34,12 +34,12 @@
34
34
  "author": "Vasyl Boroviak",
35
35
  "license": "MIT",
36
36
  "peerDependencies": {
37
- "@grpc/grpc-js": "^1.1.7",
38
- "@grpc/proto-loader": "^0.7.5",
39
- "bullmq": "^3.10.1",
40
- "express": "^4.18.2",
41
- "micro": "^10.0.1",
42
- "node-fetch": "^2.6.9"
37
+ "@grpc/grpc-js": "1",
38
+ "@grpc/proto-loader": "0",
39
+ "bullmq": "3 - 5",
40
+ "express": "4",
41
+ "micro": "10",
42
+ "node-fetch": "2"
43
43
  },
44
44
  "peerDependenciesMeta": {
45
45
  "@grpc/grpc-js": {
@@ -62,17 +62,17 @@
62
62
  }
63
63
  },
64
64
  "devDependencies": {
65
- "@grpc/grpc-js": "^1.1.7",
66
- "@grpc/proto-loader": "^0.7.5",
67
- "bullmq": "^3.10.1",
65
+ "@grpc/grpc-js": "^1.13.4",
66
+ "@grpc/proto-loader": "^0.8.0",
67
+ "bullmq": "^5.56.9",
68
68
  "cls-hooked": "^4.2.2",
69
- "eslint": "^8.55.0",
70
- "express": "^4.18.2",
69
+ "eslint": "^8.57.1",
70
+ "express": "^4.21.2",
71
71
  "lambda-local": "^1.7.3",
72
72
  "micro": "^10.0.1",
73
- "mocha": "^10.2.0",
73
+ "mocha": "^11.7.1",
74
74
  "node-fetch": "^2.6.9",
75
- "nyc": "^15.1.0",
75
+ "nyc": "^17.1.0",
76
76
  "prettier": "^2.1.1"
77
77
  },
78
78
  "dependencies": {
@@ -141,6 +141,8 @@ module.exports = require("stampit")({
141
141
  [p]: {
142
142
  // The protocol implementation strategy.
143
143
  transport: null,
144
+ // The maximum time to wait until returning the ALLSERVER_CLIENT_TIMEOUT error. 0 means - no timeout.
145
+ timeout: 0,
144
146
  // Disable any exception throwing when calling any methods. Otherwise, throws network and server errors.
145
147
  neverThrow: true,
146
148
  // Automatically find (introspect) and call corresponding remote procedures. Use only the methods defined in client side.
@@ -173,6 +175,7 @@ module.exports = require("stampit")({
173
175
  {
174
176
  uri,
175
177
  transport,
178
+ timeout,
176
179
  neverThrow,
177
180
  dynamicMethods,
178
181
  autoIntrospect,
@@ -183,6 +186,7 @@ module.exports = require("stampit")({
183
186
  },
184
187
  { stamp }
185
188
  ) {
189
+ this[p].timeout = timeout != null ? timeout : this[p].timeout;
186
190
  this[p].neverThrow = neverThrow != null ? neverThrow : this[p].neverThrow;
187
191
  this[p].dynamicMethods = dynamicMethods != null ? dynamicMethods : this[p].dynamicMethods;
188
192
  this[p].autoIntrospect = autoIntrospect != null ? autoIntrospect : this[p].autoIntrospect;
@@ -218,10 +222,10 @@ module.exports = require("stampit")({
218
222
  try {
219
223
  // This is supposed to be executed only once (per uri) unless it throws.
220
224
  // There are only 3 situations when this throws:
221
- // * the "introspect" method not found on server,
222
- // * the network request is malformed,
225
+ // * the "introspect" method not found on server, (GRPC)
226
+ // * the network request is malformed, (HTTP-like)
223
227
  // * couldn't connect to the remote host.
224
- ctx.result = await transport.introspect(ctx);
228
+ ctx.result = await this._callTransport(ctx);
225
229
  } catch (err) {
226
230
  ctx.result = {
227
231
  success: false,
@@ -281,19 +285,41 @@ module.exports = require("stampit")({
281
285
  return await runMiddlewares(middlewares);
282
286
  },
283
287
 
288
+ _callTransport(ctx) {
289
+ const transportMethod = ctx.isIntrospection ? "introspect" : "call";
290
+ // In JavaScript if the `timeout` is null or undefined or some other object this condition will return `false`
291
+ if (this[p].timeout > 0) {
292
+ return Promise.race([
293
+ this[p].transport[transportMethod](ctx),
294
+ new Promise((resolve) =>
295
+ setTimeout(
296
+ () =>
297
+ resolve({
298
+ success: false,
299
+ code: "ALLSERVER_CLIENT_TIMEOUT",
300
+ message: `The remote procedure ${ctx.procedureName} timed out in ${this[p].timeout} ms`,
301
+ }),
302
+ this[p].timeout
303
+ )
304
+ ),
305
+ ]);
306
+ }
307
+
308
+ return this[p].transport[transportMethod](ctx);
309
+ },
310
+
284
311
  async call(procedureName, arg) {
285
312
  if (!arg) arg = {};
286
313
  if (!arg._) arg._ = {};
287
314
  arg._.procedureName = procedureName;
288
315
 
289
- const transport = this[p].transport;
290
316
  const defaultCtx = { procedureName, arg, client: this };
291
- const ctx = transport.createCallContext(defaultCtx);
317
+ const ctx = this[p].transport.createCallContext(defaultCtx);
292
318
 
293
319
  await this._callMiddlewares(ctx, "before", async () => {
294
320
  if (!ctx.result) {
295
321
  try {
296
- ctx.result = await transport.call(ctx);
322
+ ctx.result = await this._callTransport(ctx);
297
323
  } catch (err) {
298
324
  if (!this[p].neverThrow) throw err;
299
325
 
@@ -81,8 +81,6 @@ module.exports = require("./Transport").compose({
81
81
  err ? reject(err) : resolve(result)
82
82
  );
83
83
  });
84
-
85
- return this.server.start();
86
84
  },
87
85
  stopServer() {
88
86
  return new Promise((r) => this.server.tryShutdown(r));
@@ -60,6 +60,7 @@ module.exports = require("./Transport").compose({
60
60
  return new Promise((r) => {
61
61
  if (this.server.closeIdleConnections) this.server.closeIdleConnections();
62
62
  this.server.close(r);
63
+ if (this.server.closeAllConnections) this.server.closeAllConnections();
63
64
  });
64
65
  },
65
66