@openfn/ws-worker 1.14.0 → 1.14.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
+ ## 1.14.1
4
+
5
+ ### Patch Changes
6
+
7
+ - d765843: Fix an issue where the server can attempt to claim even while it's waiting to shut down
8
+ - 667e3bf: Improve logging of errors returned by lightning
9
+ - d765843: Fix an issue where the --backoff server argument only accepts integer values
10
+
3
11
  ## 1.14.0
4
12
 
5
13
  ### Minor Changes
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { EventEmitter as EventEmitter2 } from "node:events";
3
3
  import { promisify } from "node:util";
4
4
  import { exec as _exec } from "node:child_process";
5
- import * as Sentry5 from "@sentry/node";
5
+ import * as Sentry6 from "@sentry/node";
6
6
  import Koa from "koa";
7
7
  import bodyParser from "koa-bodyparser";
8
8
  import koaLogger from "koa-logger";
@@ -82,6 +82,10 @@ var tryWithBackoff = (fn, opts = {}) => {
82
82
  await fn();
83
83
  resolve();
84
84
  } catch (e) {
85
+ if (e?.abort) {
86
+ cancelled = true;
87
+ return reject();
88
+ }
85
89
  if (opts.isCancelled()) {
86
90
  return resolve();
87
91
  }
@@ -111,6 +115,7 @@ var tryWithBackoff = (fn, opts = {}) => {
111
115
  var try_with_backoff_default = tryWithBackoff;
112
116
 
113
117
  // src/api/claim.ts
118
+ import * as Sentry from "@sentry/node";
114
119
  import crypto from "node:crypto";
115
120
  import * as jose from "jose";
116
121
  import { createMockLogger } from "@openfn/logger";
@@ -128,6 +133,13 @@ var verifyToken = async (token, publicKey) => {
128
133
  };
129
134
  var { DEPLOYED_POD_NAME, WORKER_NAME } = process.env;
130
135
  var NAME = WORKER_NAME || DEPLOYED_POD_NAME;
136
+ var ClaimError = class extends Error {
137
+ constructor(e) {
138
+ super(e);
139
+ // This breaks the parenting backoff loop
140
+ this.abort = true;
141
+ }
142
+ };
131
143
  var claim = (app, logger = mockLogger, options = {}) => {
132
144
  return new Promise((resolve, reject) => {
133
145
  const { maxWorkers = 5 } = options;
@@ -135,11 +147,17 @@ var claim = (app, logger = mockLogger, options = {}) => {
135
147
  const activeWorkers = Object.keys(app.workflows).length;
136
148
  if (activeWorkers >= maxWorkers) {
137
149
  app.workloop?.stop(`server at capacity (${activeWorkers}/${maxWorkers})`);
138
- return reject(new Error("Server at capacity"));
150
+ return reject(new ClaimError("Server at capacity"));
139
151
  }
140
152
  if (!app.queueChannel) {
141
- logger.debug("skipping claim attempt: websocket unavailable");
142
- return reject(new Error("No websocket available"));
153
+ logger.warn("skipping claim attempt: websocket unavailable");
154
+ return reject(new ClaimError("No websocket available"));
155
+ }
156
+ if (app.queueChannel.state === "closed") {
157
+ const e = new ClaimError("queue closed");
158
+ Sentry.captureException(e);
159
+ logger.warn("skipping claim attempt: channel closed");
160
+ return reject(e);
143
161
  }
144
162
  logger.debug(`requesting run (capacity ${activeWorkers}/${maxWorkers})`);
145
163
  const start = Date.now();
@@ -202,6 +220,7 @@ var startWorkloop = (app, logger, minBackoff, maxBackoff, maxWorkers) => {
202
220
  if (!cancelled) {
203
221
  setTimeout(workLoop, minBackoff);
204
222
  }
223
+ }).catch(() => {
205
224
  });
206
225
  }
207
226
  };
@@ -220,7 +239,7 @@ var startWorkloop = (app, logger, minBackoff, maxBackoff, maxWorkers) => {
220
239
  var workloop_default = startWorkloop;
221
240
 
222
241
  // src/api/execute.ts
223
- import * as Sentry2 from "@sentry/node";
242
+ import * as Sentry3 from "@sentry/node";
224
243
 
225
244
  // src/util/convert-lightning-plan.ts
226
245
  import crypto2 from "node:crypto";
@@ -435,12 +454,28 @@ var create_run_state_default = (plan, input) => {
435
454
  };
436
455
 
437
456
  // src/util/send-event.ts
438
- import * as Sentry from "@sentry/node";
457
+ import * as Sentry2 from "@sentry/node";
439
458
 
440
459
  // src/errors.ts
460
+ function serializeMessage(message) {
461
+ if (typeof message === "string") {
462
+ return message;
463
+ }
464
+ if (message instanceof Error) {
465
+ return message.toString();
466
+ }
467
+ if (message && typeof message === "object") {
468
+ try {
469
+ return JSON.stringify(message);
470
+ } catch {
471
+ return String(message);
472
+ }
473
+ }
474
+ return String(message);
475
+ }
441
476
  var LightningSocketError = class extends Error {
442
477
  constructor(event, message) {
443
- super(`[${event}] ${message}`);
478
+ super(`[${event}] ${serializeMessage(message)}`);
444
479
  this.name = "LightningSocketError";
445
480
  this.event = "";
446
481
  this.rejectMessage = "";
@@ -469,7 +504,7 @@ var sendEvent = (context, event, payload) => {
469
504
  if (error.rejectMessage) {
470
505
  extras.rejection_reason = error.rejectMessage;
471
506
  }
472
- Sentry.captureException(error, (scope) => {
507
+ Sentry2.captureException(error, (scope) => {
473
508
  scope.setContext("run", context2);
474
509
  scope.setExtras(extras);
475
510
  return scope;
@@ -802,8 +837,8 @@ function execute(channel, engine, logger, plan, input, options = {}, onFinish =
802
837
  options,
803
838
  onFinish
804
839
  };
805
- Sentry2.withIsolationScope(async () => {
806
- Sentry2.addBreadcrumb({
840
+ Sentry3.withIsolationScope(async () => {
841
+ Sentry3.addBreadcrumb({
807
842
  category: "run",
808
843
  message: "Executing run: loading metadata",
809
844
  level: "info",
@@ -815,7 +850,7 @@ function execute(channel, engine, logger, plan, input, options = {}, onFinish =
815
850
  const addEvent = (eventName, handler) => {
816
851
  const wrappedFn = async (event) => {
817
852
  if (eventName !== "workflow-log") {
818
- Sentry2.addBreadcrumb({
853
+ Sentry3.addBreadcrumb({
819
854
  category: "event",
820
855
  message: eventName,
821
856
  level: "info"
@@ -827,7 +862,7 @@ function execute(channel, engine, logger, plan, input, options = {}, onFinish =
827
862
  logger.info(`${plan.id} :: ${lightningEvent} :: OK`);
828
863
  } catch (e) {
829
864
  if (!e.reportedToSentry) {
830
- Sentry2.captureException(e);
865
+ Sentry3.captureException(e);
831
866
  logger.error(e);
832
867
  }
833
868
  }
@@ -871,7 +906,7 @@ function execute(channel, engine, logger, plan, input, options = {}, onFinish =
871
906
  }
872
907
  }
873
908
  try {
874
- Sentry2.addBreadcrumb({
909
+ Sentry3.addBreadcrumb({
875
910
  category: "run",
876
911
  message: "run metadata loaded: starting run",
877
912
  level: "info",
@@ -881,7 +916,7 @@ function execute(channel, engine, logger, plan, input, options = {}, onFinish =
881
916
  });
882
917
  engine.execute(plan, loadedInput, { resolvers, ...options });
883
918
  } catch (e) {
884
- Sentry2.addBreadcrumb({
919
+ Sentry3.addBreadcrumb({
885
920
  category: "run",
886
921
  message: "exception in run",
887
922
  level: "info",
@@ -948,7 +983,7 @@ var healthcheck_default = (ctx) => {
948
983
  };
949
984
 
950
985
  // src/channels/run.ts
951
- import * as Sentry3 from "@sentry/node";
986
+ import * as Sentry4 from "@sentry/node";
952
987
  var joinRunChannel = (socket, token, runId, logger, timeout = 30) => {
953
988
  return new Promise((resolve, reject) => {
954
989
  let didReceiveOk = false;
@@ -967,12 +1002,12 @@ var joinRunChannel = (socket, token, runId, logger, timeout = 30) => {
967
1002
  resolve({ channel, run });
968
1003
  }
969
1004
  }).receive("error", (err) => {
970
- Sentry3.captureException(err);
1005
+ Sentry4.captureException(err);
971
1006
  logger.error(`error connecting to ${channelName}`, err);
972
1007
  channel?.leave();
973
1008
  reject(err);
974
1009
  }).receive("timeout", (err) => {
975
- Sentry3.captureException(err);
1010
+ Sentry4.captureException(err);
976
1011
  logger.error(`Timeout for ${channelName}`, err);
977
1012
  channel?.leave();
978
1013
  reject(err);
@@ -990,7 +1025,7 @@ var run_default = joinRunChannel;
990
1025
 
991
1026
  // src/channels/worker-queue.ts
992
1027
  import EventEmitter from "node:events";
993
- import * as Sentry4 from "@sentry/node";
1028
+ import * as Sentry5 from "@sentry/node";
994
1029
  import { Socket as PhxSocket } from "phoenix";
995
1030
  import { WebSocket } from "ws";
996
1031
  import { API_VERSION } from "@openfn/lexicon/lightning";
@@ -1019,13 +1054,13 @@ var worker_token_default = generateWorkerToken;
1019
1054
  // src/channels/worker-queue.ts
1020
1055
  var connectToWorkerQueue = (endpoint, serverId, secret, timeout = 10, logger, SocketConstructor = PhxSocket) => {
1021
1056
  const events = new EventEmitter();
1022
- Sentry4.addBreadcrumb({
1057
+ Sentry5.addBreadcrumb({
1023
1058
  category: "lifecycle",
1024
1059
  message: "Connecting to worker queue",
1025
1060
  level: "info"
1026
1061
  });
1027
1062
  worker_token_default(secret, serverId, logger).then(async (token) => {
1028
- Sentry4.addBreadcrumb({
1063
+ Sentry5.addBreadcrumb({
1029
1064
  category: "lifecycle",
1030
1065
  message: "Worker token generated",
1031
1066
  level: "info"
@@ -1044,7 +1079,7 @@ var connectToWorkerQueue = (endpoint, serverId, secret, timeout = 10, logger, So
1044
1079
  let didOpen = false;
1045
1080
  let shouldReportConnectionError = true;
1046
1081
  socket.onOpen(() => {
1047
- Sentry4.addBreadcrumb({
1082
+ Sentry5.addBreadcrumb({
1048
1083
  category: "lifecycle",
1049
1084
  message: "Web socket connected",
1050
1085
  level: "info"
@@ -1070,7 +1105,7 @@ var connectToWorkerQueue = (endpoint, serverId, secret, timeout = 10, logger, So
1070
1105
  events.emit("disconnect");
1071
1106
  });
1072
1107
  socket.onError((e) => {
1073
- Sentry4.addBreadcrumb({
1108
+ Sentry5.addBreadcrumb({
1074
1109
  category: "lifecycle",
1075
1110
  message: "Error in web socket connection",
1076
1111
  level: "info"
@@ -1078,7 +1113,7 @@ var connectToWorkerQueue = (endpoint, serverId, secret, timeout = 10, logger, So
1078
1113
  if (shouldReportConnectionError) {
1079
1114
  logger.debug("Reporting connection error to sentry");
1080
1115
  shouldReportConnectionError = false;
1081
- Sentry4.captureException(e);
1116
+ Sentry5.captureException(e);
1082
1117
  }
1083
1118
  if (!didOpen) {
1084
1119
  events.emit("error", e.message);
@@ -1185,11 +1220,11 @@ function createServer(engine, options = {}) {
1185
1220
  app.events = new EventEmitter2();
1186
1221
  app.engine = engine;
1187
1222
  if (options.sentryDsn) {
1188
- Sentry5.init({
1223
+ Sentry6.init({
1189
1224
  environment: options.sentryEnv,
1190
1225
  dsn: options.sentryDsn
1191
1226
  });
1192
- Sentry5.setupKoaErrorHandler(app);
1227
+ Sentry6.setupKoaErrorHandler(app);
1193
1228
  }
1194
1229
  app.use(bodyParser());
1195
1230
  app.use(
@@ -1206,7 +1241,7 @@ function createServer(engine, options = {}) {
1206
1241
  router.get("/", healthcheck_default);
1207
1242
  app.options = options;
1208
1243
  app.resumeWorkloop = () => {
1209
- if (options.noLoop) {
1244
+ if (options.noLoop || app.destroyed) {
1210
1245
  return;
1211
1246
  }
1212
1247
  if (!app.workloop || app.workloop?.isStopped()) {
@@ -1306,7 +1341,7 @@ function createServer(engine, options = {}) {
1306
1341
  shutdown = true;
1307
1342
  logger.always(`${signal} RECEIVED: CLOSING SERVER`);
1308
1343
  await app.destroy();
1309
- process.exit();
1344
+ process.exit(0);
1310
1345
  }
1311
1346
  };
1312
1347
  process.on("SIGINT", () => exit("SIGINT"));
package/dist/start.js CHANGED
@@ -142,7 +142,7 @@ var runtime_engine_default = createMock;
142
142
  import { EventEmitter as EventEmitter3 } from "node:events";
143
143
  import { promisify } from "node:util";
144
144
  import { exec as _exec } from "node:child_process";
145
- import * as Sentry5 from "@sentry/node";
145
+ import * as Sentry6 from "@sentry/node";
146
146
  import Koa from "koa";
147
147
  import bodyParser from "koa-bodyparser";
148
148
  import koaLogger from "koa-logger";
@@ -222,6 +222,10 @@ var tryWithBackoff = (fn, opts = {}) => {
222
222
  await fn();
223
223
  resolve5();
224
224
  } catch (e) {
225
+ if (e?.abort) {
226
+ cancelled = true;
227
+ return reject();
228
+ }
225
229
  if (opts.isCancelled()) {
226
230
  return resolve5();
227
231
  }
@@ -251,6 +255,7 @@ var tryWithBackoff = (fn, opts = {}) => {
251
255
  var try_with_backoff_default = tryWithBackoff;
252
256
 
253
257
  // src/api/claim.ts
258
+ import * as Sentry from "@sentry/node";
254
259
  import crypto2 from "node:crypto";
255
260
  import * as jose from "jose";
256
261
  import { createMockLogger } from "@openfn/logger";
@@ -268,6 +273,13 @@ var verifyToken = async (token, publicKey) => {
268
273
  };
269
274
  var { DEPLOYED_POD_NAME, WORKER_NAME } = process.env;
270
275
  var NAME = WORKER_NAME || DEPLOYED_POD_NAME;
276
+ var ClaimError = class extends Error {
277
+ constructor(e) {
278
+ super(e);
279
+ // This breaks the parenting backoff loop
280
+ this.abort = true;
281
+ }
282
+ };
271
283
  var claim = (app, logger2 = mockLogger, options = {}) => {
272
284
  return new Promise((resolve5, reject) => {
273
285
  const { maxWorkers = 5 } = options;
@@ -275,11 +287,17 @@ var claim = (app, logger2 = mockLogger, options = {}) => {
275
287
  const activeWorkers = Object.keys(app.workflows).length;
276
288
  if (activeWorkers >= maxWorkers) {
277
289
  app.workloop?.stop(`server at capacity (${activeWorkers}/${maxWorkers})`);
278
- return reject(new Error("Server at capacity"));
290
+ return reject(new ClaimError("Server at capacity"));
279
291
  }
280
292
  if (!app.queueChannel) {
281
- logger2.debug("skipping claim attempt: websocket unavailable");
282
- return reject(new Error("No websocket available"));
293
+ logger2.warn("skipping claim attempt: websocket unavailable");
294
+ return reject(new ClaimError("No websocket available"));
295
+ }
296
+ if (app.queueChannel.state === "closed") {
297
+ const e = new ClaimError("queue closed");
298
+ Sentry.captureException(e);
299
+ logger2.warn("skipping claim attempt: channel closed");
300
+ return reject(e);
283
301
  }
284
302
  logger2.debug(`requesting run (capacity ${activeWorkers}/${maxWorkers})`);
285
303
  const start = Date.now();
@@ -342,6 +360,7 @@ var startWorkloop = (app, logger2, minBackoff2, maxBackoff2, maxWorkers) => {
342
360
  if (!cancelled) {
343
361
  setTimeout(workLoop, minBackoff2);
344
362
  }
363
+ }).catch(() => {
345
364
  });
346
365
  }
347
366
  };
@@ -360,7 +379,7 @@ var startWorkloop = (app, logger2, minBackoff2, maxBackoff2, maxWorkers) => {
360
379
  var workloop_default = startWorkloop;
361
380
 
362
381
  // src/api/execute.ts
363
- import * as Sentry2 from "@sentry/node";
382
+ import * as Sentry3 from "@sentry/node";
364
383
 
365
384
  // src/util/convert-lightning-plan.ts
366
385
  import crypto3 from "node:crypto";
@@ -575,12 +594,28 @@ var create_run_state_default = (plan, input) => {
575
594
  };
576
595
 
577
596
  // src/util/send-event.ts
578
- import * as Sentry from "@sentry/node";
597
+ import * as Sentry2 from "@sentry/node";
579
598
 
580
599
  // src/errors.ts
600
+ function serializeMessage(message) {
601
+ if (typeof message === "string") {
602
+ return message;
603
+ }
604
+ if (message instanceof Error) {
605
+ return message.toString();
606
+ }
607
+ if (message && typeof message === "object") {
608
+ try {
609
+ return JSON.stringify(message);
610
+ } catch {
611
+ return String(message);
612
+ }
613
+ }
614
+ return String(message);
615
+ }
581
616
  var LightningSocketError = class extends Error {
582
617
  constructor(event, message) {
583
- super(`[${event}] ${message}`);
618
+ super(`[${event}] ${serializeMessage(message)}`);
584
619
  this.name = "LightningSocketError";
585
620
  this.event = "";
586
621
  this.rejectMessage = "";
@@ -609,7 +644,7 @@ var sendEvent = (context, event, payload) => {
609
644
  if (error.rejectMessage) {
610
645
  extras.rejection_reason = error.rejectMessage;
611
646
  }
612
- Sentry.captureException(error, (scope) => {
647
+ Sentry2.captureException(error, (scope) => {
613
648
  scope.setContext("run", context2);
614
649
  scope.setExtras(extras);
615
650
  return scope;
@@ -942,8 +977,8 @@ function execute(channel, engine, logger2, plan, input, options = {}, onFinish =
942
977
  options,
943
978
  onFinish
944
979
  };
945
- Sentry2.withIsolationScope(async () => {
946
- Sentry2.addBreadcrumb({
980
+ Sentry3.withIsolationScope(async () => {
981
+ Sentry3.addBreadcrumb({
947
982
  category: "run",
948
983
  message: "Executing run: loading metadata",
949
984
  level: "info",
@@ -955,7 +990,7 @@ function execute(channel, engine, logger2, plan, input, options = {}, onFinish =
955
990
  const addEvent = (eventName, handler) => {
956
991
  const wrappedFn = async (event) => {
957
992
  if (eventName !== "workflow-log") {
958
- Sentry2.addBreadcrumb({
993
+ Sentry3.addBreadcrumb({
959
994
  category: "event",
960
995
  message: eventName,
961
996
  level: "info"
@@ -967,7 +1002,7 @@ function execute(channel, engine, logger2, plan, input, options = {}, onFinish =
967
1002
  logger2.info(`${plan.id} :: ${lightningEvent} :: OK`);
968
1003
  } catch (e) {
969
1004
  if (!e.reportedToSentry) {
970
- Sentry2.captureException(e);
1005
+ Sentry3.captureException(e);
971
1006
  logger2.error(e);
972
1007
  }
973
1008
  }
@@ -1011,7 +1046,7 @@ function execute(channel, engine, logger2, plan, input, options = {}, onFinish =
1011
1046
  }
1012
1047
  }
1013
1048
  try {
1014
- Sentry2.addBreadcrumb({
1049
+ Sentry3.addBreadcrumb({
1015
1050
  category: "run",
1016
1051
  message: "run metadata loaded: starting run",
1017
1052
  level: "info",
@@ -1021,7 +1056,7 @@ function execute(channel, engine, logger2, plan, input, options = {}, onFinish =
1021
1056
  });
1022
1057
  engine.execute(plan, loadedInput, { resolvers, ...options });
1023
1058
  } catch (e) {
1024
- Sentry2.addBreadcrumb({
1059
+ Sentry3.addBreadcrumb({
1025
1060
  category: "run",
1026
1061
  message: "exception in run",
1027
1062
  level: "info",
@@ -1088,7 +1123,7 @@ var healthcheck_default = (ctx) => {
1088
1123
  };
1089
1124
 
1090
1125
  // src/channels/run.ts
1091
- import * as Sentry3 from "@sentry/node";
1126
+ import * as Sentry4 from "@sentry/node";
1092
1127
  var joinRunChannel = (socket, token, runId, logger2, timeout = 30) => {
1093
1128
  return new Promise((resolve5, reject) => {
1094
1129
  let didReceiveOk = false;
@@ -1107,12 +1142,12 @@ var joinRunChannel = (socket, token, runId, logger2, timeout = 30) => {
1107
1142
  resolve5({ channel, run: run2 });
1108
1143
  }
1109
1144
  }).receive("error", (err) => {
1110
- Sentry3.captureException(err);
1145
+ Sentry4.captureException(err);
1111
1146
  logger2.error(`error connecting to ${channelName}`, err);
1112
1147
  channel?.leave();
1113
1148
  reject(err);
1114
1149
  }).receive("timeout", (err) => {
1115
- Sentry3.captureException(err);
1150
+ Sentry4.captureException(err);
1116
1151
  logger2.error(`Timeout for ${channelName}`, err);
1117
1152
  channel?.leave();
1118
1153
  reject(err);
@@ -1130,7 +1165,7 @@ var run_default = joinRunChannel;
1130
1165
 
1131
1166
  // src/channels/worker-queue.ts
1132
1167
  import EventEmitter2 from "node:events";
1133
- import * as Sentry4 from "@sentry/node";
1168
+ import * as Sentry5 from "@sentry/node";
1134
1169
  import { Socket as PhxSocket } from "phoenix";
1135
1170
  import { WebSocket } from "ws";
1136
1171
  import { API_VERSION } from "@openfn/lexicon/lightning";
@@ -1159,13 +1194,13 @@ var worker_token_default = generateWorkerToken;
1159
1194
  // src/channels/worker-queue.ts
1160
1195
  var connectToWorkerQueue = (endpoint, serverId, secret, timeout = 10, logger2, SocketConstructor = PhxSocket) => {
1161
1196
  const events = new EventEmitter2();
1162
- Sentry4.addBreadcrumb({
1197
+ Sentry5.addBreadcrumb({
1163
1198
  category: "lifecycle",
1164
1199
  message: "Connecting to worker queue",
1165
1200
  level: "info"
1166
1201
  });
1167
1202
  worker_token_default(secret, serverId, logger2).then(async (token) => {
1168
- Sentry4.addBreadcrumb({
1203
+ Sentry5.addBreadcrumb({
1169
1204
  category: "lifecycle",
1170
1205
  message: "Worker token generated",
1171
1206
  level: "info"
@@ -1184,7 +1219,7 @@ var connectToWorkerQueue = (endpoint, serverId, secret, timeout = 10, logger2, S
1184
1219
  let didOpen = false;
1185
1220
  let shouldReportConnectionError = true;
1186
1221
  socket.onOpen(() => {
1187
- Sentry4.addBreadcrumb({
1222
+ Sentry5.addBreadcrumb({
1188
1223
  category: "lifecycle",
1189
1224
  message: "Web socket connected",
1190
1225
  level: "info"
@@ -1210,7 +1245,7 @@ var connectToWorkerQueue = (endpoint, serverId, secret, timeout = 10, logger2, S
1210
1245
  events.emit("disconnect");
1211
1246
  });
1212
1247
  socket.onError((e) => {
1213
- Sentry4.addBreadcrumb({
1248
+ Sentry5.addBreadcrumb({
1214
1249
  category: "lifecycle",
1215
1250
  message: "Error in web socket connection",
1216
1251
  level: "info"
@@ -1218,7 +1253,7 @@ var connectToWorkerQueue = (endpoint, serverId, secret, timeout = 10, logger2, S
1218
1253
  if (shouldReportConnectionError) {
1219
1254
  logger2.debug("Reporting connection error to sentry");
1220
1255
  shouldReportConnectionError = false;
1221
- Sentry4.captureException(e);
1256
+ Sentry5.captureException(e);
1222
1257
  }
1223
1258
  if (!didOpen) {
1224
1259
  events.emit("error", e.message);
@@ -1325,11 +1360,11 @@ function createServer(engine, options = {}) {
1325
1360
  app.events = new EventEmitter3();
1326
1361
  app.engine = engine;
1327
1362
  if (options.sentryDsn) {
1328
- Sentry5.init({
1363
+ Sentry6.init({
1329
1364
  environment: options.sentryEnv,
1330
1365
  dsn: options.sentryDsn
1331
1366
  });
1332
- Sentry5.setupKoaErrorHandler(app);
1367
+ Sentry6.setupKoaErrorHandler(app);
1333
1368
  }
1334
1369
  app.use(bodyParser());
1335
1370
  app.use(
@@ -1346,7 +1381,7 @@ function createServer(engine, options = {}) {
1346
1381
  router.get("/", healthcheck_default);
1347
1382
  app.options = options;
1348
1383
  app.resumeWorkloop = () => {
1349
- if (options.noLoop) {
1384
+ if (options.noLoop || app.destroyed) {
1350
1385
  return;
1351
1386
  }
1352
1387
  if (!app.workloop || app.workloop?.isStopped()) {
@@ -1446,7 +1481,7 @@ function createServer(engine, options = {}) {
1446
1481
  shutdown = true;
1447
1482
  logger2.always(`${signal} RECEIVED: CLOSING SERVER`);
1448
1483
  await app.destroy();
1449
- process.exit();
1484
+ process.exit(0);
1450
1485
  }
1451
1486
  };
1452
1487
  process.on("SIGINT", () => exit("SIGINT"));
@@ -6350,7 +6385,10 @@ function parseArgs(argv) {
6350
6385
  WORKER_SOCKET_TIMEOUT_SECONDS,
6351
6386
  WORKER_STATE_PROPS_TO_REMOVE
6352
6387
  } = process.env;
6353
- const parser2 = yargs_default(hideBin(argv)).command("server", "Start a ws-worker server").option("port", {
6388
+ const parser2 = yargs_default(hideBin(argv)).command("server", "Start a ws-worker server").option("debug", {
6389
+ hidden: true,
6390
+ type: "boolean"
6391
+ }).option("port", {
6354
6392
  alias: "p",
6355
6393
  description: `Port to run the server on. Default ${DEFAULT_PORT2}. Env: WORKER_PORT`,
6356
6394
  type: "number"
@@ -6472,11 +6510,11 @@ if (args.lightning === "mock") {
6472
6510
  if (!args.secret) {
6473
6511
  args.secret = "abdefg";
6474
6512
  }
6475
- } else if (!args.secret) {
6513
+ } else if (!args.debug && !args.secret) {
6476
6514
  logger.error("WORKER_SECRET is not set");
6477
6515
  process.exit(1);
6478
6516
  }
6479
- var [minBackoff, maxBackoff] = args.backoff.split("/").map((n) => parseInt(n, 10) * 1e3);
6517
+ var [minBackoff, maxBackoff] = args.backoff.split("/").map((n) => parseFloat(n) * 1e3);
6480
6518
  function engineReady(engine) {
6481
6519
  logger.debug("Creating worker instance");
6482
6520
  const workerOptions = {
@@ -6487,7 +6525,6 @@ function engineReady(engine) {
6487
6525
  sentryDsn: args.sentryDsn,
6488
6526
  sentryEnv: args.sentryEnv,
6489
6527
  noLoop: !args.loop,
6490
- // TODO need to feed this through properly
6491
6528
  backoff: {
6492
6529
  min: minBackoff,
6493
6530
  max: maxBackoff
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfn/ws-worker",
3
- "version": "1.14.0",
3
+ "version": "1.14.1",
4
4
  "description": "A Websocket Worker to connect Lightning to a Runtime Engine",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",