cry-ebus2 4.0.8 → 4.0.12

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 (59) hide show
  1. package/CLAUDE.md +77 -0
  2. package/dist/EbusConfiguration.d.mts +2 -2
  3. package/dist/EbusConfiguration.d.mts.map +1 -1
  4. package/dist/EbusUnpackedResult.d.mts +0 -2
  5. package/dist/EbusUnpackedResult.d.mts.map +1 -1
  6. package/dist/block.mjs.map +1 -1
  7. package/dist/broker.d.mts +1 -4
  8. package/dist/broker.d.mts.map +1 -1
  9. package/dist/broker.mjs +67 -41
  10. package/dist/broker.mjs.map +1 -1
  11. package/dist/clientBlocking.mjs.map +1 -1
  12. package/dist/clientNonBlocking.d.mts.map +1 -1
  13. package/dist/clientNonBlocking.mjs +6 -3
  14. package/dist/clientNonBlocking.mjs.map +1 -1
  15. package/dist/run/call.mjs +15 -24
  16. package/dist/run/call.mjs.map +1 -1
  17. package/dist/run/calling.mjs.map +1 -1
  18. package/dist/run/callingBurst.mjs.map +1 -1
  19. package/dist/run/ping.mjs.map +1 -1
  20. package/dist/run/pub.mjs.map +1 -1
  21. package/dist/run/sub.mjs.map +1 -1
  22. package/dist/run/workers.mjs.map +1 -1
  23. package/dist/serialize.mjs.map +1 -1
  24. package/dist/service.d.mts +0 -2
  25. package/dist/service.d.mts.map +1 -1
  26. package/dist/service.mjs +45 -15
  27. package/dist/service.mjs.map +1 -1
  28. package/dist/sub.d.mts +0 -1
  29. package/dist/sub.d.mts.map +1 -1
  30. package/dist/sub.mjs.map +1 -1
  31. package/dist/test/config.test.mjs +3 -4
  32. package/dist/test/config.test.mjs.map +1 -1
  33. package/dist/test/echo.test.mjs +4 -5
  34. package/dist/test/echo.test.mjs.map +1 -1
  35. package/dist/test/reject.test.mjs +3 -4
  36. package/dist/test/reject.test.mjs.map +1 -1
  37. package/dist/test/services.test.mjs +7 -9
  38. package/dist/test/services.test.mjs.map +1 -1
  39. package/dist/test/stress.test.mjs +4 -5
  40. package/dist/test/stress.test.mjs.map +1 -1
  41. package/dist/test/timing.test.mjs +5 -6
  42. package/dist/test/timing.test.mjs.map +1 -1
  43. package/dist/worker.d.mts +5 -1
  44. package/dist/worker.d.mts.map +1 -1
  45. package/dist/worker.mjs +35 -14
  46. package/dist/worker.mjs.map +1 -1
  47. package/package.json +3 -2
  48. package/src/EbusConfiguration.mts +2 -2
  49. package/src/broker.mts +69 -48
  50. package/src/clientNonBlocking.mts +7 -3
  51. package/src/run/call.mts +22 -34
  52. package/src/service.mts +38 -15
  53. package/src/test/config.test.mts +3 -4
  54. package/src/test/echo.test.mts +4 -5
  55. package/src/test/reject.test.mts +3 -4
  56. package/src/test/services.test.mts +7 -9
  57. package/src/test/stress.test.mts +4 -5
  58. package/src/test/timing.test.mts +5 -6
  59. package/src/worker.mts +39 -18
package/dist/worker.mjs CHANGED
@@ -11,14 +11,16 @@ export class Worker {
11
11
  constructor(service, config = {}) {
12
12
  this.service = "";
13
13
  this.exitingAfterTimeout = false;
14
+ this.stopped = false;
15
+ this.onExit = async () => { await this.exit(); };
14
16
  this.service = service || this.service;
15
17
  this.configuration = loadConfiguration(prefixes, config);
16
18
  this.address = this.configuration.address;
17
19
  this.lastHeartbeat = Date.now();
18
20
  this.processing = false;
19
- process.on("SIGINT", async () => { await this.exit(); });
20
- process.on("SIGTERM", async () => { await this.exit(); });
21
- process.on("SIGABRT", async () => { await this.exit(); });
21
+ process.on("SIGINT", this.onExit);
22
+ process.on("SIGTERM", this.onExit);
23
+ process.on("SIGABRT", this.onExit);
22
24
  }
23
25
  async exit() {
24
26
  setTimeout(() => {
@@ -26,7 +28,7 @@ export class Worker {
26
28
  process.exit(1);
27
29
  }, 1000);
28
30
  try {
29
- await this.stop();
31
+ await this.shutdown();
30
32
  log.status(`worker for ${this.service} stopped`);
31
33
  process.exit(0);
32
34
  }
@@ -62,13 +64,13 @@ export class Worker {
62
64
  }, this.configuration.heartbeatInterval);
63
65
  }
64
66
  async start() {
67
+ this.stopped = false;
65
68
  log.debug(`worker for ${this.service} is starting`);
66
69
  const loop = async () => {
67
70
  this.socket = new Dealer();
68
71
  this.socket.reconnectInterval = 100;
69
72
  await this.socket.connect(this.configuration.address);
70
73
  await this.socket.send([null, Header.Worker, Message.Ready, this.service]);
71
- await this.socket.receive();
72
74
  log.status(`started worker for ${this.service} on ${this.configuration.address}`);
73
75
  this.startHeartbeat();
74
76
  for await (const [blank1, header, type, client, blank2, reqId, optBuff, req] of this.socket) {
@@ -109,6 +111,8 @@ export class Worker {
109
111
  log.error(`worker for '${this.service} error in internal loop`);
110
112
  log.error(err);
111
113
  }
114
+ if (this.stopped)
115
+ break;
112
116
  try {
113
117
  await this.stop();
114
118
  }
@@ -126,11 +130,14 @@ export class Worker {
126
130
  async processRequest(reqId, optBuff, type, req, client) {
127
131
  let opts = serialize.unpack(optBuff);
128
132
  log.debug(`worker for ${this.service} received request ${type} with opts`, opts);
129
- let timeout = opts.receiveTimeout || this.configuration.receiveTimeout;
133
+ const requestedTimeout = opts.receiveTimeout || this.configuration.receiveTimeout;
134
+ const dispatchedAt = opts._dispatchedAt || Date.now();
135
+ const elapsed = Date.now() - dispatchedAt;
136
+ const timeout = Math.max(0, requestedTimeout - elapsed);
130
137
  let responseMessageType = Message.Reply;
131
- let promises = [
138
+ const promises = [
132
139
  this.process(unpack(req, opts), opts),
133
- sleep(timeout, new EbusRejectError("timeout", `timeout in worker for '${this.service}' after ${timeout} ms`, opts))
140
+ sleep(timeout, new EbusRejectError("timeout", `timeout in worker for '${this.service}' after ${requestedTimeout} ms (${elapsed}ms in queue, ${timeout}ms remaining)`, opts))
134
141
  ];
135
142
  let rep;
136
143
  try {
@@ -215,23 +222,37 @@ export class Worker {
215
222
  }
216
223
  process.nextTick(() => process.exit(1));
217
224
  }
225
+ /** Closes the current connection. Worker will reconnect unless shutdown() was called. */
218
226
  async stop() {
219
227
  log.debug(`worker for ${this.service} is stopping`);
220
228
  if (this.interval)
221
229
  clearInterval(this.interval);
222
230
  this.interval = undefined;
223
231
  if (this.socket && !this.socket.closed) {
224
- await this.socket.send([
225
- null,
226
- Header.Worker,
227
- Message.Disconnect,
228
- this.service,
229
- ]);
232
+ try {
233
+ await this.socket.send([
234
+ null,
235
+ Header.Worker,
236
+ Message.Disconnect,
237
+ this.service,
238
+ ]);
239
+ }
240
+ catch (_a) {
241
+ log.debug(`worker for ${this.service} disconnect send failed (expected during shutdown)`);
242
+ }
230
243
  log.debug(`worker for ${this.service} is closing socket`);
231
244
  this.socket.close();
232
245
  }
233
246
  this.socket = undefined;
234
247
  }
248
+ /** Permanently stops the worker, preventing reconnection. */
249
+ async shutdown() {
250
+ this.stopped = true;
251
+ process.off("SIGINT", this.onExit);
252
+ process.off("SIGTERM", this.onExit);
253
+ process.off("SIGABRT", this.onExit);
254
+ await this.stop();
255
+ }
235
256
  async publish(channel, message) {
236
257
  if (!this.socket) {
237
258
  log.error(`worker for '${this.service}' not connected, cannot publish to ${channel}`, message);
@@ -1 +1 @@
1
- {"version":3,"file":"worker.mjs","sourceRoot":"","sources":["../src/worker.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAG,SAAS,EAAC,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAG/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAElD,MAAM,QAAQ,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;AACxC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;AAE7B,MAAM,OAAO,MAAM;IAUf,YAAY,OAAgB,EAAE,SAAsC,EAAE;QARtE,YAAO,GAAG,EAAE,CAAA;QAMJ,wBAAmB,GAAG,KAAK,CAAA;QAG/B,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;QACvC,IAAI,CAAC,aAAa,GAAG,iBAAiB,CAAC,QAAQ,EAAC,MAAM,CAAC,CAAA;QACvD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAA;QACzC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC/B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAA;QAEvB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA,CAAC,CAAC,CAAC,CAAA;QACvD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA,CAAC,CAAC,CAAC,CAAA;QACxD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA,CAAC,CAAC,CAAC,CAAA;IAC5D,CAAC;IAED,KAAK,CAAC,IAAI;QACN,UAAU,CAAC,GAAG,EAAE;YACZ,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,qBAAqB,CAAC,CAAA;YAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACnB,CAAC,EAAE,IAAI,CAAC,CAAA;QACR,IAAI;YACA,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,OAAO,UAAU,CAAC,CAAA;YAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACnB;QAAC,WAAM,GAAG;IACf,CAAC;IAED,cAAc;QACV,IAAI,IAAI,CAAC,QAAQ;YAAE,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAE/B,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YAEnC,IAAI,IAAI,CAAC,UAAU;gBAAE,OAAO;YAE5B,IAAI;gBAEA,IAAI;oBACA,IAAI,IAAI,CAAC,MAAM,EAAE;wBACb,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;qBAC7F;iBACJ;gBAAC,OAAO,GAAG,EAAE;oBACV,GAAG,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;oBACxC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;iBACjB;gBAED,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;gBACtD,IAAI,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;oBACrD,OAAO,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAA;oBAChE,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;iBACpB;aACJ;YAAC,OAAO,GAAG,EAAE;gBACV,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,kBAAkB,CAAC,CAAA;gBACvD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;aACjB;QAEL,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAE,CAAA;IAC7C,CAAC;IAED,KAAK,CAAC,KAAK;QAEP,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,cAAc,CAAC,CAAA;QAEnD,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;YAEpB,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;YAC1B,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,GAAG,CAAA;YACnC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;YACrD,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;YAC1E,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAA;YAC3B,GAAG,CAAC,MAAM,CAAC,sBAAsB,IAAI,CAAC,OAAO,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAA;YAEjF,IAAI,CAAC,cAAc,EAAE,CAAA;YAErB,IAAI,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE;gBAEzF,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAE/B,IAAI;oBAEA,QAAQ,IAAI,CAAC,QAAQ,EAAE,EAAE;wBACrB,KAAK,OAAO,CAAC,QAAQ;4BAEjB,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,OAAO,kCAAkC,CAAC,CAAA;4BACxE,MAAM;wBAEV,KAAK,OAAO,CAAC,SAAS;4BAElB,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,iCAAiC,CAAC,CAAA;4BACtE,MAAM;wBAEV,KAAK,OAAO,CAAC,kBAAkB;4BAE3B,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,OAAO,0CAA0C,CAAC,CAAA;4BAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;4BACf,MAAM;wBAEV,KAAK,OAAO,CAAC,OAAO;4BAEhB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;4BACtB,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;4BAC5D,IAAI,CAAC,UAAU,GAAG,KAAK,CAAA;4BACvB,MAAM;wBAEV;4BAEI,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,gCAAgC,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;4BACxI,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;qBAE7E;iBAIJ;gBAAC,OAAO,GAAG,EAAE;oBACV,GAAG,CAAC,KAAK,CAAC,wBAAwB,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAA;oBACrE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;iBACjB;aAEJ;QAGL,CAAC,CAAA;QAED,SAAU;YAEN,IAAI;gBACA,MAAM,IAAI,EAAE,CAAA;aACf;YAAC,OAAO,GAAG,EAAE;gBACV,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAA;gBAC/D,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;aACjB;YACD,IAAI;gBACA,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;aACpB;YAAC,OAAO,GAAG,EAAE;gBACV,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,OAAO,8BAA8B,CAAC,CAAA;gBACpE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;aACjB;YAED,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,OAAO,eAAe,CAAC,CAAA;SAExD;IAEL,CAAC;IAED,yCAAyC;IAClC,KAAK,CAAC,OAAO,CAAC,GAAO,EAAE,GAAQ,EAAE,IAAS;QAE7C,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,OAAO,KAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5E,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,KAAa,EAAE,OAAe,EAAE,IAAY,EAAE,GAAW,EAAE,MAAc;QAElG,IAAI,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,CAAgC,CAAA;QACnE,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,qBAAqB,IAAI,YAAY,EAAE,IAAI,CAAC,CAAA;QAChF,IAAI,OAAO,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,aAAa,CAAC,cAAc,CAAA;QACtE,IAAI,mBAAmB,GAAqE,OAAO,CAAC,KAAK,CAAA;QAEzG,IAAI,QAAQ,GAAG;YACX,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;YACrC,KAAK,CAAC,OAAO,EAAE,IAAI,eAAe,CAAC,SAAS,EAAE,0BAA0B,IAAI,CAAC,OAAO,WAAW,OAAO,KAAK,EAAE,IAAI,CAAC,CAAC;SACtH,CAAA;QAED,IAAI,GAAQ,CAAA;QAEZ,IAAI;YACA,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAClC,IAAI,GAAG,YAAY,eAAe,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE;gBAC5D,GAAG,CAAC,IAAI,CAAC,kCAAkC,IAAI,CAAC,OAAO,WAAW,OAAO,iBAAiB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;gBACjH,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;gBAC3B,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAA;gBACrC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;aACpD;SACJ;QAAC,OAAO,GAAO,EAAE;YACd,GAAG,GAAG,GAAG,CAAA;YACT,IAAI,CAAC,CAAC,GAAG,YAAY,eAAe,CAAC,EAAE;gBACnC,GAAG,GAAG,IAAI,eAAe,CAAC,OAAO,EAAE,wBAAwB,IAAI,CAAC,OAAO,sBAAsB,GAAG,CAAC,OAAO,GAAG,EAAE,GAAG,CAAC,CAAC;gBAClH,mBAAmB,GAAG,OAAO,CAAC,KAAK,CAAC;aACvC;YACD,IAAI,GAAG,YAAY,eAAe,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;gBAC1D,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAA;YACzC,IAAI,GAAG,YAAY,eAAe,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ;gBACzD,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAA;YACxC,IAAI,GAAG,YAAY,eAAe,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO;gBACxD,mBAAmB,GAAG,OAAO,CAAC,KAAK,CAAA;YAEvC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,IAAI,CAAE,CAAC;SAC/C;QAED,IAAI,IAAI,GAAG,GAAG,CAAC;QAEf,IAAI,GAAG,YAAY,eAAe;YAC9B,IAAI,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,GAAG,CAAA;QAE5D,IAAI,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,MAAK,SAAS,IAAI,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,MAAK,SAAS,EAAE;YACpD,MAAM,QAAQ,GAAG,GAAuD,CAAA;YACxE,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAA;YACpB,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAA;SACvB;QAED,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,kBAAkB,mBAAmB,EAAE,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QAEtF,MAAM,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAEtE,IAAI,mBAAmB,KAAK,OAAO,CAAC,OAAO,IAAI,mBAAmB,KAAK,OAAO,CAAC,KAAK;YAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACxH,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,mBAA4B,EAAE,MAAc,EAAE,KAAa,EAAE,IAAiC,EAAE,IAAS;QAC/H,IAAI;YACA,MAAM,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC;gBACpB,IAAI;gBACJ,MAAM,CAAC,MAAM;gBACb,mBAAmB;gBACnB,MAAM;gBACN,IAAI;gBACJ,KAAK;gBACL,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;gBACpB,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;aACnB,CAAC,CAAA;SACL;QAAC,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,KAAK,CAAC,4BAA4B,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAA;YAC5E,MAAM,GAAG,CAAA;SACZ;IACL,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC1B,IAAI,IAAI,CAAC,mBAAmB;YAAE,OAAM;QACpC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAA;QAE/B,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,OAAO,mEAAmE,CAAC,CAAA;QAEvG,IAAI;YACA,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;gBACpC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;oBACnB,IAAI;oBACJ,MAAM,CAAC,MAAM;oBACb,OAAO,CAAC,QAAQ;oBAChB,IAAI,CAAC,OAAO;iBACf,CAAC,CAAA;aACL;SACJ;QAAC,OAAO,GAAG,EAAE;YACV,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,iDAAiD,CAAC,CAAA;YACtF,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;SACjB;QAED,IAAI;YACA,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;SACpB;QAAC,OAAO,GAAG,EAAE;YACV,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,qCAAqC,CAAC,CAAA;YAC1E,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;SACjB;QAED,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAC3C,CAAC;IAED,KAAK,CAAC,IAAI;QAEN,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,cAAc,CAAC,CAAA;QAGnD,IAAI,IAAI,CAAC,QAAQ;YAAE,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAA;QAEzB,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YACpC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACnB,IAAI;gBACJ,MAAM,CAAC,MAAM;gBACb,OAAO,CAAC,UAAU;gBAClB,IAAI,CAAC,OAAO;aACf,CAAC,CAAA;YACF,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,OAAO,oBAAoB,CAAC,CAAA;YACzD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;SACtB;QACD,IAAI,CAAC,MAAM,GAAG,SAAS,CAAA;IAC3B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,OAAY;QACvC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACd,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,OAAO,sCAAsC,OAAO,EAAE,EAAC,OAAO,CAAC,CAAA;YAC7F,OAAO;SACV;QACD,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;QAC1F,GAAG,CAAC,KAAK,CAAC,6BAA6B,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;QAE5D,6BAA6B;QAC7B,mDAAmD;QACnD,kFAAkF;QAClF,+DAA+D;QAC/D,yEAAyE;IAC7E,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAQ,EAAE,IAAkC;QACtD,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,OAAO,2BAA2B,CAAC,CAAA;IAClF,CAAC;CACJ"}
1
+ {"version":3,"file":"worker.mjs","sourceRoot":"","sources":["../src/worker.mts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "cry-ebus2",
3
- "version": "4.0.8",
3
+ "version": "4.0.12",
4
4
  "description": "",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.mts",
7
7
  "type": "module",
8
8
  "scripts": {
9
9
  "build": "tsc",
10
- "test": "mocha 'dist/test/**/*.test.mjs' --exit",
10
+ "test": "mocha 'dist/test/**/*.test.mjs' --exit --timeout 30000",
11
+ "test:single": "mocha --exit --timeout 30000",
11
12
  "pretest": "npm run build"
12
13
  },
13
14
  "repository": {
@@ -2,8 +2,8 @@
2
2
  export interface EbusConfiguration {
3
3
  address: string;
4
4
  pubAddress: string;
5
- sendHighWaterMark: 1;
6
- sendTimeout: 1;
5
+ sendHighWaterMark: number;
6
+ sendTimeout: number;
7
7
  port: number;
8
8
  pubPort: number;
9
9
  server: string;
package/src/broker.mts CHANGED
@@ -11,19 +11,25 @@ const prefixes = ["EBUS_BROKER", "EBUS"]
11
11
  const log = new Log(prefixes)
12
12
 
13
13
  export class Broker {
14
- socket: Router = new Router({ sendHighWaterMark: 1, sendTimeout: 1 })
14
+ socket!: Router
15
15
  services: Map<string, Service> = new Map()
16
16
  workers: Map<string, Buffer> = new Map()
17
17
  configuration: EbusConfiguration
18
18
  publisher: Publisher
19
19
  interval: ReturnType<typeof setInterval> | undefined
20
20
 
21
+ private readonly onExit = async () => { await this.exit() }
22
+
21
23
  constructor(configuration: Partial<EbusConfiguration> = {} ) {
22
24
  this.configuration = loadConfiguration(prefixes, configuration)
25
+ this.socket = new Router({
26
+ sendHighWaterMark: this.configuration.sendHighWaterMark,
27
+ sendTimeout: this.configuration.sendTimeout,
28
+ })
23
29
  this.publisher = new Publisher
24
- process.on("SIGINT", async () => { await this.exit() })
25
- process.on("SIGTERM", async () => { await this.exit() })
26
- process.on("SIGABRT", async () => { await this.exit() })
30
+ process.on("SIGINT", this.onExit)
31
+ process.on("SIGTERM", this.onExit)
32
+ process.on("SIGABRT", this.onExit)
27
33
  }
28
34
 
29
35
  async exit()
@@ -105,27 +111,45 @@ export class Broker {
105
111
  }
106
112
 
107
113
  async stop() {
114
+ process.off("SIGINT", this.onExit)
115
+ process.off("SIGTERM", this.onExit)
116
+ process.off("SIGABRT", this.onExit)
108
117
 
109
118
  if (this.interval) clearInterval(this.interval)
110
119
  this.interval = undefined;
111
120
 
112
121
  log.status("broker stopping")
113
- await this.publisher.send(['ebus/stop', pack(new Date(), {})])
122
+
123
+ try {
124
+ if (!this.publisher.closed)
125
+ await this.publisher.send(['ebus/stop', pack(new Date(), {})])
126
+ } catch {
127
+ log.debug("broker failed to publish stop event")
128
+ }
114
129
 
115
130
  // notify all workers that we're shutting down
116
131
  for (const service of this.services.values()) {
117
132
  for (const [, buff] of service.workers.entries()) {
118
- await this.socket.send([
119
- buff,
120
- null,
121
- Header.Worker,
122
- Message.Shutdown,
123
- ])
133
+ try {
134
+ if (!this.socket.closed)
135
+ await this.socket.send([
136
+ buff,
137
+ null,
138
+ Header.Worker,
139
+ Message.Shutdown,
140
+ ])
141
+ } catch {
142
+ log.debug("broker failed to notify worker during shutdown")
143
+ }
124
144
  }
125
145
  }
126
146
 
127
- if (!this.socket.closed) await this.socket.close()
128
- if (!this.publisher.closed) await this.publisher.close()
147
+ for (const service of this.services.values()) service.destroy()
148
+ this.services.clear()
149
+ this.workers.clear()
150
+
151
+ if (!this.socket.closed) this.socket.close()
152
+ if (!this.publisher.closed) this.publisher.close()
129
153
  log.status("broker stopped")
130
154
  }
131
155
 
@@ -239,8 +263,13 @@ export class Broker {
239
263
  }
240
264
 
241
265
  private async publishWorkersAndServices() {
242
- await this.publisher.send(['ebus/workers', pack(this.getServicesWithWorkes(), {})])
243
- await this.publisher.send(['ebus/services', pack(this.getServicesStatus(), {})])
266
+ if (this.publisher.closed) return
267
+ try {
268
+ await this.publisher.send(['ebus/workers', pack(this.getServicesWithWorkes(), {})])
269
+ await this.publisher.send(['ebus/services', pack(this.getServicesStatus(), {})])
270
+ } catch {
271
+ log.debug("broker failed to publish workers/services (expected during shutdown)")
272
+ }
244
273
  }
245
274
 
246
275
  register(worker: Buffer, service: Buffer) {
@@ -255,21 +284,24 @@ export class Broker {
255
284
  }
256
285
 
257
286
  async dispatchReply(type: Buffer, worker: Buffer, client: Buffer, ...rep: Buffer[]) {
258
- const service = this.getWorkerService(worker)
259
- let serviceOfWorker = this.getService(service)
287
+ const workerKey = worker.toString("hex")
288
+ const service = this.workers.get(workerKey)
289
+ let serviceOfWorker = this.getService(service!)
260
290
  if (serviceOfWorker) await serviceOfWorker.dispatchReply(type, worker, client, ...rep)
261
291
  else log.error(`cannot dispatch reply for ${service} ${serviceOfWorker} to client`,client)
262
292
  }
263
293
 
264
294
  deregister(worker: Buffer) {
265
- const service = this.getWorkerService(worker)
266
- this.getService(service)?.deregister(worker)
267
- this.workers.delete(worker.toString("hex"))
295
+ const workerKey = worker.toString("hex")
296
+ const service = this.workers.get(workerKey)
297
+ this.getService(service!)?.deregister(worker)
298
+ this.workers.delete(workerKey)
268
299
  }
269
300
 
270
301
  updateHeartbeatForWorker(worker: Buffer) {
271
- const service = this.getWorkerService(worker)
272
- this.getService(service)?.updateHeartbeat(worker)
302
+ const workerKey = worker.toString("hex")
303
+ const service = this.workers.get(workerKey)
304
+ this.getService(service!)?.updateHeartbeat(worker)
273
305
  }
274
306
 
275
307
  getService(name: Buffer): Service | undefined {
@@ -285,42 +317,31 @@ export class Broker {
285
317
  }
286
318
  }
287
319
 
288
- getWorkerService(worker: Buffer): Buffer {
289
- return this.workers.get(worker.toString("hex"))!
290
- }
291
-
292
320
  setWorkerService(worker: Buffer, service: Buffer) {
293
321
  this.workers.set(worker.toString("hex"), service)
294
322
  }
295
323
 
296
- getServicesWithWorkes()
297
- {
298
- let services = Array.from(this.services.values()).filter(v => v.workers.size)
299
- let names = [... new Set(services.map(s => s.name))];
324
+ getServicesWithWorkes(): string[] {
325
+ const names: string[] = []
326
+ for (const service of this.services.values()) {
327
+ if (service.workers.size) names.push(service.name)
328
+ }
300
329
  return names
301
330
  }
302
331
 
303
332
  getServicesStatus() {
304
- let services = Array.from(this.services.values())
305
- let names = services.map(s => {
306
- return {
307
- name: s.name,
308
- workers: s.workers.size,
309
- requests: s.requests.length
310
- }
311
- })
312
- return names
333
+ const result: { name: string, workers: number, requests: number }[] = []
334
+ for (const s of this.services.values()) {
335
+ result.push({ name: s.name, workers: s.workers.size, requests: s.requests.length })
336
+ }
337
+ return result
313
338
  }
314
339
 
315
340
  getActiveWorkes() {
316
- let workers = Array.from(this.services.values()).map(service =>
317
- {
318
- return {
319
- name: service.name,
320
- nWorkers: service.workers.size,
321
- nRequests: service.requests.length
322
- }
323
- })
324
- return workers
341
+ const result: { name: string, nWorkers: number, nRequests: number }[] = []
342
+ for (const s of this.services.values()) {
343
+ result.push({ name: s.name, nWorkers: s.workers.size, nRequests: s.requests.length })
344
+ }
345
+ return result
325
346
  }
326
347
  }
@@ -15,6 +15,10 @@ import { TypedEmitter } from 'tiny-typed-emitter';
15
15
  const prefixes = ["EBUS_CLIENT", "EBUS"]
16
16
  let log = new Log(prefixes)
17
17
 
18
+ const TIMEOUT_BUFFER = Buffer.from(Message.Timeout)
19
+ const ERROR_BUFFER = Buffer.from(Message.Error)
20
+ const EMPTY_BUFFER = Buffer.from([0])
21
+
18
22
 
19
23
  declare type ResultProcessor<T> = (this:ClientNonBlocking,{ data, opts, type }: { data: any, opts: Partial<EbusRequestOptions>, type: Buffer }) => T | undefined | EbusUnpackedResult<T>;
20
24
 
@@ -260,12 +264,12 @@ export class ClientNonBlocking extends TypedEmitter<EbusClientEvents> {
260
264
  if (err?.errno === 35) {
261
265
  this.lastError = new EbusRejectError("timeout", `timeout in client requesting '${service}' after ${receiveTimeout} ms`)
262
266
  log.debug(`request expired at client waiting for '${service}' after ${receiveTimeout} ms`, req)
263
- let processed = processResult.bind(this)({ data: undefined, opts: {}, type: Buffer.from(Message.Timeout) })
267
+ let processed = processResult.bind(this)({ data: undefined, opts: {}, type: TIMEOUT_BUFFER })
264
268
  promise.resolve(processed)
265
269
  } else {
266
270
  this.lastError = new EbusRejectError("error", `error in client requesting '${service}' after ${receiveTimeout} ms`)
267
271
  log.debug(`request errored at client waiting for '${service}' after ${receiveTimeout} ms`, req)
268
- let processed = processResult.bind(this)({ data: undefined, opts: {}, type: Buffer.from(Message.Error) })
272
+ let processed = processResult.bind(this)({ data: undefined, opts: {}, type: ERROR_BUFFER })
269
273
  promise.resolve(processed);
270
274
  }
271
275
 
@@ -298,7 +302,7 @@ export class ClientNonBlocking extends TypedEmitter<EbusClientEvents> {
298
302
  requestRecord[1][4] = undefined
299
303
  }
300
304
  // resolve and return
301
- promise.resolve({ data: undefined, opts: {}, type: Buffer.from([0]) });
305
+ promise.resolve({ data: undefined, opts: {}, type: EMPTY_BUFFER });
302
306
  }
303
307
  }
304
308
  }
package/src/run/call.mts CHANGED
@@ -1,8 +1,7 @@
1
1
 
2
2
  import { objStrToJson } from "cry-helpers";
3
3
  import { config } from "dotenv";
4
- import { Command, program } from "commander"
5
- import { exit } from "process";
4
+ import { program } from "commander"
6
5
  import { Client } from "../client.mjs";
7
6
  import { EbusRequestOptions } from "../EbusRequestOptions.mjs";
8
7
 
@@ -12,26 +11,18 @@ program.version('0.0.2');
12
11
 
13
12
  let client = new Client()
14
13
 
15
- interface MyCommand extends Command {
14
+ interface ProgramOpts {
16
15
  timeout: number
17
16
  repeat: string
18
- silent: string
19
- dryRun: string
17
+ silent: boolean
18
+ dryRun: boolean
20
19
  depth: string
21
- measure: string
22
- }
23
-
24
- const myProgram = program as MyCommand
25
-
26
- function exitProgram(message: string)
27
- {
28
- console.error(message)
29
- exit(2)
20
+ measure: boolean
30
21
  }
31
22
 
32
23
  program
33
24
  .description('calls a worker')
34
- .option('-t, --timeout <ms>', 'timeout in milliseconds', Number.parseInt, 2000)
25
+ .option('-t, --timeout <ms>', 'timeout in milliseconds', (v: string) => parseInt(v, 10), 2000)
35
26
  .option('-r, --repeat <repeat>', 'repeat n times', "1")
36
27
  .option('-d, --depth <depth>', 'json output depth', "3")
37
28
  .option('-n, --dry-run', 'do not call, just report')
@@ -39,38 +30,35 @@ program
39
30
  .option('-S, --silent', 'do not output progress')
40
31
  .arguments('<worker> [params]')
41
32
  .action(async (worker,params) => {
42
-
33
+ const o = program.opts<ProgramOpts>()
43
34
  let workload = tryParseJson(params || '')
44
- let opts: Partial<EbusRequestOptions> | undefined = {}
45
- let repeat = parseInt(myProgram.repeat)
35
+ let reqOpts: Partial<EbusRequestOptions> | undefined = {}
36
+ let repeat = parseInt(o.repeat)
46
37
  let start = new Date().valueOf()
47
38
  if (isNaN(repeat)) repeat = 1;
48
-
49
- console.log('myProgram.timeout', myProgram.timeout, typeof myProgram.timeout);
50
-
51
- if (isNaN(myProgram.timeout)) myProgram.timeout = 1000;
52
- if (typeof myProgram.timeout==="number") opts.receiveTimeout=myProgram.timeout
53
- if (Object.keys(opts).length === 0) opts = undefined;
54
- if (!myProgram.silent) {
39
+
40
+ reqOpts.receiveTimeout = o.timeout
41
+ if (Object.keys(reqOpts).length === 0) reqOpts = undefined;
42
+ if (!o.silent) {
55
43
  console.log('');
56
- console.log(`${myProgram.dryRun ? 'would ' : ''}call \x1b[7m ${worker} \x1b[27m`, opts)
44
+ console.log(`${o.dryRun ? 'would ' : ''}call \x1b[7m ${worker} \x1b[27m`, reqOpts)
57
45
  if (repeat!==1)
58
- console.log(`repeat \x1b[7m ${repeat} \x1b[27m times`, opts)
46
+ console.log(`repeat \x1b[7m ${repeat} \x1b[27m times`, reqOpts)
59
47
  if (workload) console.log(`with ${typeof workload} message`, workload)
60
48
  console.log('')
61
49
  }
62
-
63
- if (!myProgram.dryRun) {
50
+
51
+ if (!o.dryRun) {
64
52
  try {
65
53
 
66
54
  for (let i = 0; i < repeat; i++ ) {
67
- let res = await client.request(worker, workload, opts)
68
- let depth = Number.parseInt(myProgram.depth) || 3
55
+ let res = await client.request(worker, workload, reqOpts)
56
+ let depth = Number.parseInt(o.depth) || 3
69
57
  console.dir(res, { depth });
70
58
  if (client.lastError) console.log(client.lastError);
71
- if (!myProgram.silent) console.log();
59
+ if (!o.silent) console.log();
72
60
  }
73
-
61
+
74
62
  } catch (err: any) {
75
63
  console.error(`\x1b[31munexpected error\x1b[0m ${err.message}`)
76
64
  console.log(err)
@@ -78,7 +66,7 @@ program
78
66
  }
79
67
  }
80
68
 
81
- if (myProgram.measure) console.log("elapsed time: ", new Date().valueOf() - start, "ms\n");
69
+ if (o.measure) console.log("elapsed time: ", new Date().valueOf() - start, "ms\n");
82
70
 
83
71
  process.exit(0)
84
72
  })
package/src/service.mts CHANGED
@@ -1,6 +1,7 @@
1
- import { Log } from "cry-helpers"
1
+ import { Log, serialize } from "cry-helpers"
2
2
  import { Router } from "zeromq"
3
3
  import { Header, Message } from "./types.mjs"
4
+ import type { EbusRequestOptions } from "./EbusRequestOptions.mjs"
4
5
 
5
6
  const prefixes = ["EBUS_BROKER", "EBUS"]
6
7
  const log = new Log(prefixes)
@@ -24,7 +25,8 @@ export class Service {
24
25
  }
25
26
 
26
27
  async dispatchRequest(reqId: Buffer, client: Buffer, timeout: number, opts: Buffer, req: Buffer) {
27
- this.requests.push([client, req, reqId, opts, (Date.now()+timeout) ])
28
+ const absoluteTimeout = timeout * 10
29
+ this.requests.push([client, req, reqId, opts, (Date.now() + absoluteTimeout)])
28
30
  await this.dispatchPending()
29
31
  }
30
32
 
@@ -51,9 +53,20 @@ export class Service {
51
53
 
52
54
  async dispatchPending() {
53
55
 
54
- // purge time-outed requests
56
+ // purge expired requests in-place and notify clients
55
57
  const now = Date.now()
56
- this.requests = this.requests.filter( ([v1,v2,v3,v4,until]) => until >= now)
58
+ let writeIdx = 0
59
+ for (let i = 0; i < this.requests.length; i++) {
60
+ const entry = this.requests[i]
61
+ if (entry[4] < now) {
62
+ try {
63
+ await this.socket.send([entry[0], null, Header.Client, Message.Timeout, entry[2]])
64
+ } catch { /* client may have disconnected */ }
65
+ } else {
66
+ this.requests[writeIdx++] = entry
67
+ }
68
+ }
69
+ this.requests.length = writeIdx
57
70
 
58
71
  while (this.workers.size && this.requests.length) {
59
72
  // find least loaded worker
@@ -69,7 +82,13 @@ export class Service {
69
82
  continue;
70
83
  }
71
84
 
72
- const [client, req, reqId, opts, until] = this.requests.shift()!
85
+ const [client, req, reqId, opts] = this.requests.shift()!
86
+
87
+ // stamp dispatch time into opts so worker can measure from dispatch, not from receive
88
+ let parsedOpts: Partial<EbusRequestOptions> & { _dispatchedAt?: number }
89
+ try { parsedOpts = serialize.unpack(opts) ?? {} } catch { parsedOpts = {} }
90
+ parsedOpts._dispatchedAt = Date.now()
91
+ const stampedOpts = serialize.pack(parsedOpts)
73
92
 
74
93
  this.dispatched++;
75
94
  this.loads.set(workerKey, (this.loads.get(workerKey)||0)+1)
@@ -83,7 +102,7 @@ export class Service {
83
102
  client,
84
103
  null,
85
104
  reqId,
86
- opts,
105
+ stampedOpts,
87
106
  req,
88
107
  ])
89
108
  }
@@ -123,14 +142,18 @@ export class Service {
123
142
  }
124
143
 
125
144
  private async returnHeartbeatToWorker(worker: Buffer) {
126
- await this.socket.send([
127
- worker,
128
- null,
129
- Header.Worker,
130
- Message.Heartbeat,
131
- null,
132
- null,
133
- null,
134
- ])
145
+ try {
146
+ await this.socket.send([
147
+ worker,
148
+ null,
149
+ Header.Worker,
150
+ Message.Heartbeat,
151
+ null,
152
+ null,
153
+ null,
154
+ ])
155
+ } catch {
156
+ log.debug(`broker failed to return heartbeat to worker for ${this.name}`)
157
+ }
135
158
  }
136
159
  }
@@ -15,7 +15,7 @@ describe('config', function () {
15
15
  let client: Client
16
16
 
17
17
  before(async () => {
18
- const config = { port: TEST_PORT }
18
+ const config = { port: TEST_PORT, pubPort: TEST_PORT + 100, sendHighWaterMark: 100, sendTimeout: 500 }
19
19
  broker = new Broker(config)
20
20
  broker.start()
21
21
  worker = new EchoWorker(undefined, config)
@@ -27,9 +27,8 @@ describe('config', function () {
27
27
 
28
28
  after(async () => {
29
29
  client.stop()
30
- await worker.stop()
31
- broker.stop()
32
- // Give time for cleanup
30
+ await worker.shutdown()
31
+ await broker.stop()
33
32
  await new Promise(resolve => setTimeout(resolve, 100))
34
33
  })
35
34
 
@@ -17,7 +17,7 @@ describe('echo worker', function () {
17
17
  let client: Client
18
18
 
19
19
  before(async () => {
20
- const config = { port: TEST_PORT }
20
+ const config = { port: TEST_PORT, pubPort: TEST_PORT + 100, sendHighWaterMark: 100, sendTimeout: 500 }
21
21
  broker = new Broker(config)
22
22
  broker.start()
23
23
  echoWorker = new EchoWorker(undefined, config)
@@ -31,10 +31,9 @@ describe('echo worker', function () {
31
31
 
32
32
  after(async () => {
33
33
  client.stop()
34
- await echoWorker.stop()
35
- await delayWorker.stop()
36
- broker.stop()
37
- // Give time for cleanup
34
+ await echoWorker.shutdown()
35
+ await delayWorker.shutdown()
36
+ await broker.stop()
38
37
  await new Promise(resolve => setTimeout(resolve, 100))
39
38
  })
40
39