@openfn/ws-worker 0.2.0 → 0.2.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # ws-worker
2
2
 
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - ad8f6e9: Improve robustness of server connectivity
8
+ - Updated dependencies [704e7b6]
9
+ - @openfn/engine-multi@0.1.7
10
+
3
11
  ## 0.2.0
4
12
 
5
13
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import Koa from 'koa';
2
2
  import { SanitizePolicies, Logger } from '@openfn/logger';
3
- import { RuntimeEngine } from '@openfn/engine-multi';
4
3
  import { Channel as Channel$1 } from 'phoenix';
5
4
  import { ExecutionPlan } from '@openfn/runtime';
5
+ import { RuntimeEngine } from '@openfn/engine-multi';
6
6
 
7
7
  type ExitReasonStrings =
8
8
  | 'success'
@@ -85,7 +85,7 @@ interface ServerApp extends Koa {
85
85
  workflows: Record<string, true | Context>;
86
86
  execute: ({ id, token }: CLAIM_ATTEMPT) => Promise<void>;
87
87
  destroy: () => void;
88
- killWorkloop: () => void;
88
+ killWorkloop?: () => void;
89
89
  }
90
90
  declare function createServer(engine: RuntimeEngine, options?: ServerOptions): ServerApp;
91
91
 
package/dist/index.js CHANGED
@@ -80,6 +80,11 @@ var claim = (app, logger = mockLogger, maxWorkers = 5) => {
80
80
  app.execute(attempt);
81
81
  resolve();
82
82
  });
83
+ }).receive("error", () => {
84
+ logger.debug("pull err");
85
+ }).receive("timeout", () => {
86
+ logger.debug("pull timeout");
87
+ reject(new Error("timeout"));
83
88
  });
84
89
  });
85
90
  };
@@ -423,6 +428,7 @@ async function loadAttempt(channel) {
423
428
  }
424
429
 
425
430
  // src/channels/worker-queue.ts
431
+ import EventEmitter from "node:events";
426
432
  import { Socket as PhxSocket } from "phoenix";
427
433
  import { WebSocket } from "ws";
428
434
 
@@ -448,9 +454,9 @@ var generateWorkerToken = async (secret, workerId) => {
448
454
  var worker_token_default = generateWorkerToken;
449
455
 
450
456
  // src/channels/worker-queue.ts
451
- var connectToWorkerQueue = (endpoint, serverId, secret, SocketConstructor = PhxSocket) => {
452
- return new Promise(async (done, reject) => {
453
- const token = await worker_token_default(secret, serverId);
457
+ var connectToWorkerQueue = (endpoint, serverId, secret, logger, SocketConstructor = PhxSocket) => {
458
+ const events = new EventEmitter();
459
+ worker_token_default(secret, serverId).then((token) => {
454
460
  const socket = new SocketConstructor(endpoint, {
455
461
  params: { token },
456
462
  transport: WebSocket
@@ -460,20 +466,27 @@ var connectToWorkerQueue = (endpoint, serverId, secret, SocketConstructor = PhxS
460
466
  didOpen = true;
461
467
  const channel = socket.channel("worker:queue");
462
468
  channel.join().receive("ok", () => {
463
- done({ socket, channel });
469
+ logger.debug("Connected to worker queue socket");
470
+ events.emit("connect", { socket, channel });
464
471
  }).receive("error", (e) => {
465
- console.log("ERROR", e);
472
+ logger.error("ERROR", e);
466
473
  }).receive("timeout", (e) => {
467
- console.log("TIMEOUT", e);
474
+ logger.error("TIMEOUT", e);
468
475
  });
469
476
  });
477
+ socket.onClose((_e) => {
478
+ logger.debug("queue socket closed");
479
+ events.emit("disconnect");
480
+ });
470
481
  socket.onError((e) => {
471
482
  if (!didOpen) {
472
- reject(e);
483
+ events.emit("error", e.message);
484
+ didOpen = false;
473
485
  }
474
486
  });
475
487
  socket.connect();
476
488
  });
489
+ return events;
477
490
  };
478
491
  var worker_queue_default = connectToWorkerQueue;
479
492
 
@@ -481,17 +494,13 @@ var worker_queue_default = connectToWorkerQueue;
481
494
  var DEFAULT_PORT = 1234;
482
495
  var MIN_BACKOFF = 1e3;
483
496
  var MAX_BACKOFF = 1e3 * 30;
484
- function connect(app, engine, logger, options = {}) {
497
+ function connect(app, logger, options = {}) {
485
498
  logger.debug("Connecting to Lightning at", options.lightning);
486
- worker_queue_default(options.lightning, app.id, options.secret).then(({ socket, channel }) => {
499
+ const onConnect = ({ socket, channel }) => {
487
500
  logger.success("Connected to Lightning at", options.lightning);
488
501
  app.socket = socket;
489
502
  app.channel = channel;
490
503
  if (!options.noLoop) {
491
- if (app.killWorkloop) {
492
- logger.info("Terminating old workloop");
493
- app.killWorkloop();
494
- }
495
504
  logger.info("Starting workloop");
496
505
  app.killWorkloop = workloop_default(
497
506
  app,
@@ -510,17 +519,25 @@ function connect(app, engine, logger, options = {}) {
510
519
  );
511
520
  logger.break();
512
521
  }
513
- }).catch((e) => {
522
+ };
523
+ const onDisconnect = () => {
524
+ if (app.killWorkloop) {
525
+ app.killWorkloop();
526
+ delete app.killWorkloop;
527
+ logger.info("Connection to lightning lost.");
528
+ logger.info(
529
+ "Worker will automatically reconnect when lightning is back online."
530
+ );
531
+ }
532
+ };
533
+ const onError = (e) => {
514
534
  logger.error(
515
535
  "CRITICAL ERROR: could not connect to lightning at",
516
536
  options.lightning
517
537
  );
518
538
  logger.debug(e);
519
- app.killWorkloop?.();
520
- setTimeout(() => {
521
- connect(app, engine, logger, options);
522
- }, 1e4);
523
- });
539
+ };
540
+ worker_queue_default(options.lightning, app.id, options.secret, logger).on("connect", onConnect).on("disconnect", onDisconnect).on("error", onError);
524
541
  }
525
542
  function createServer(engine, options = {}) {
526
543
  const logger = options.logger || createMockLogger2();
@@ -583,7 +600,7 @@ function createServer(engine, options = {}) {
583
600
  };
584
601
  app.use(router.routes());
585
602
  if (options.lightning) {
586
- connect(app, engine, logger, options);
603
+ connect(app, logger, options);
587
604
  } else {
588
605
  logger.warn("No lightning URL provided");
589
606
  }
package/dist/start.js CHANGED
@@ -5062,6 +5062,11 @@ var claim = (app, logger2 = mockLogger, maxWorkers = 5) => {
5062
5062
  app.execute(attempt);
5063
5063
  resolve5();
5064
5064
  });
5065
+ }).receive("error", () => {
5066
+ logger2.debug("pull err");
5067
+ }).receive("timeout", () => {
5068
+ logger2.debug("pull timeout");
5069
+ reject(new Error("timeout"));
5065
5070
  });
5066
5071
  });
5067
5072
  };
@@ -5405,6 +5410,7 @@ async function loadAttempt(channel) {
5405
5410
  }
5406
5411
 
5407
5412
  // src/channels/worker-queue.ts
5413
+ import EventEmitter2 from "node:events";
5408
5414
  import { Socket as PhxSocket } from "phoenix";
5409
5415
  import { WebSocket } from "ws";
5410
5416
 
@@ -5430,9 +5436,9 @@ var generateWorkerToken = async (secret, workerId) => {
5430
5436
  var worker_token_default = generateWorkerToken;
5431
5437
 
5432
5438
  // src/channels/worker-queue.ts
5433
- var connectToWorkerQueue = (endpoint, serverId, secret, SocketConstructor = PhxSocket) => {
5434
- return new Promise(async (done, reject) => {
5435
- const token = await worker_token_default(secret, serverId);
5439
+ var connectToWorkerQueue = (endpoint, serverId, secret, logger2, SocketConstructor = PhxSocket) => {
5440
+ const events = new EventEmitter2();
5441
+ worker_token_default(secret, serverId).then((token) => {
5436
5442
  const socket = new SocketConstructor(endpoint, {
5437
5443
  params: { token },
5438
5444
  transport: WebSocket
@@ -5442,20 +5448,27 @@ var connectToWorkerQueue = (endpoint, serverId, secret, SocketConstructor = PhxS
5442
5448
  didOpen = true;
5443
5449
  const channel = socket.channel("worker:queue");
5444
5450
  channel.join().receive("ok", () => {
5445
- done({ socket, channel });
5451
+ logger2.debug("Connected to worker queue socket");
5452
+ events.emit("connect", { socket, channel });
5446
5453
  }).receive("error", (e) => {
5447
- console.log("ERROR", e);
5454
+ logger2.error("ERROR", e);
5448
5455
  }).receive("timeout", (e) => {
5449
- console.log("TIMEOUT", e);
5456
+ logger2.error("TIMEOUT", e);
5450
5457
  });
5451
5458
  });
5459
+ socket.onClose((_e) => {
5460
+ logger2.debug("queue socket closed");
5461
+ events.emit("disconnect");
5462
+ });
5452
5463
  socket.onError((e) => {
5453
5464
  if (!didOpen) {
5454
- reject(e);
5465
+ events.emit("error", e.message);
5466
+ didOpen = false;
5455
5467
  }
5456
5468
  });
5457
5469
  socket.connect();
5458
5470
  });
5471
+ return events;
5459
5472
  };
5460
5473
  var worker_queue_default = connectToWorkerQueue;
5461
5474
 
@@ -5463,17 +5476,13 @@ var worker_queue_default = connectToWorkerQueue;
5463
5476
  var DEFAULT_PORT = 1234;
5464
5477
  var MIN_BACKOFF = 1e3;
5465
5478
  var MAX_BACKOFF = 1e3 * 30;
5466
- function connect(app, engine, logger2, options = {}) {
5479
+ function connect(app, logger2, options = {}) {
5467
5480
  logger2.debug("Connecting to Lightning at", options.lightning);
5468
- worker_queue_default(options.lightning, app.id, options.secret).then(({ socket, channel }) => {
5481
+ const onConnect = ({ socket, channel }) => {
5469
5482
  logger2.success("Connected to Lightning at", options.lightning);
5470
5483
  app.socket = socket;
5471
5484
  app.channel = channel;
5472
5485
  if (!options.noLoop) {
5473
- if (app.killWorkloop) {
5474
- logger2.info("Terminating old workloop");
5475
- app.killWorkloop();
5476
- }
5477
5486
  logger2.info("Starting workloop");
5478
5487
  app.killWorkloop = workloop_default(
5479
5488
  app,
@@ -5492,17 +5501,25 @@ function connect(app, engine, logger2, options = {}) {
5492
5501
  );
5493
5502
  logger2.break();
5494
5503
  }
5495
- }).catch((e) => {
5504
+ };
5505
+ const onDisconnect = () => {
5506
+ if (app.killWorkloop) {
5507
+ app.killWorkloop();
5508
+ delete app.killWorkloop;
5509
+ logger2.info("Connection to lightning lost.");
5510
+ logger2.info(
5511
+ "Worker will automatically reconnect when lightning is back online."
5512
+ );
5513
+ }
5514
+ };
5515
+ const onError = (e) => {
5496
5516
  logger2.error(
5497
5517
  "CRITICAL ERROR: could not connect to lightning at",
5498
5518
  options.lightning
5499
5519
  );
5500
5520
  logger2.debug(e);
5501
- app.killWorkloop?.();
5502
- setTimeout(() => {
5503
- connect(app, engine, logger2, options);
5504
- }, 1e4);
5505
- });
5521
+ };
5522
+ worker_queue_default(options.lightning, app.id, options.secret, logger2).on("connect", onConnect).on("disconnect", onDisconnect).on("error", onError);
5506
5523
  }
5507
5524
  function createServer(engine, options = {}) {
5508
5525
  const logger2 = options.logger || createMockLogger2();
@@ -5565,7 +5582,7 @@ function createServer(engine, options = {}) {
5565
5582
  };
5566
5583
  app.use(router.routes());
5567
5584
  if (options.lightning) {
5568
- connect(app, engine, logger2, options);
5585
+ connect(app, logger2, options);
5569
5586
  } else {
5570
5587
  logger2.warn("No lightning URL provided");
5571
5588
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfn/ws-worker",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "A Websocket Worker to connect Lightning to a Runtime Engine",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -21,7 +21,7 @@
21
21
  "koa-logger": "^3.2.1",
22
22
  "phoenix": "^1.7.7",
23
23
  "ws": "^8.14.1",
24
- "@openfn/engine-multi": "0.1.6",
24
+ "@openfn/engine-multi": "0.1.7",
25
25
  "@openfn/logger": "0.0.19",
26
26
  "@openfn/runtime": "0.1.0"
27
27
  },
@@ -40,7 +40,7 @@
40
40
  "tsup": "^6.2.3",
41
41
  "typescript": "^4.6.4",
42
42
  "yargs": "^17.6.2",
43
- "@openfn/lightning-mock": "1.0.7"
43
+ "@openfn/lightning-mock": "1.0.8"
44
44
  },
45
45
  "files": [
46
46
  "dist",