@openfn/ws-worker 0.5.0 → 0.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/CHANGELOG.md +25 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +67 -34
- package/dist/start.js +118 -65
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# ws-worker
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- eb10b1f: Updated start env vars and arguments
|
|
8
|
+
- 281391b: Support attemptTimeoutMs in attempt options
|
|
9
|
+
Better server logging at startup
|
|
10
|
+
Support start arguments from the environment (but prefer CLI)
|
|
11
|
+
- 2857fe6: Send the exit reason to the attempt logs
|
|
12
|
+
- Updated dependencies [281391b]
|
|
13
|
+
- @openfn/engine-multi@0.3.0
|
|
14
|
+
|
|
15
|
+
## 0.6.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- 9b9ca0c: New worker pool engine
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [0f22694]
|
|
24
|
+
- Updated dependencies [9b9ca0c]
|
|
25
|
+
- @openfn/runtime@0.2.5
|
|
26
|
+
- @openfn/engine-multi@0.3.0
|
|
27
|
+
|
|
3
28
|
## 0.5.0
|
|
4
29
|
|
|
5
30
|
### Minor Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -56,7 +56,18 @@ type Attempt = {
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
type AttemptOptions = {
|
|
59
|
+
// This is what Lightning will ssend us
|
|
60
|
+
// Note that this is the NEW terminology, so it's the timeout for the whole "attempt"
|
|
61
|
+
runTimeout?: number;
|
|
62
|
+
|
|
63
|
+
// this is the internal old terminology, which will be deprecated soon
|
|
64
|
+
attemptTimeoutMs?: number;
|
|
65
|
+
|
|
66
|
+
attemptTimeout?: number; // deprecated
|
|
67
|
+
|
|
68
|
+
// deprecated alias for timeout. Maps to "attemptTimeout" internally
|
|
59
69
|
timeout?: number;
|
|
70
|
+
|
|
60
71
|
sanitize?: SanitizePolicies;
|
|
61
72
|
};
|
|
62
73
|
|
package/dist/index.js
CHANGED
|
@@ -186,6 +186,14 @@ var mapTriggerEdgeCondition = (edge) => {
|
|
|
186
186
|
return true;
|
|
187
187
|
return condition;
|
|
188
188
|
};
|
|
189
|
+
var mapOptions = (options) => {
|
|
190
|
+
const { attemptTimeout, timeout, runTimeout, ...opts } = options;
|
|
191
|
+
const to = runTimeout || attemptTimeout || timeout;
|
|
192
|
+
if (to) {
|
|
193
|
+
opts.attemptTimeoutMs = to;
|
|
194
|
+
}
|
|
195
|
+
return opts;
|
|
196
|
+
};
|
|
189
197
|
var convert_attempt_default = (attempt) => {
|
|
190
198
|
const options = attempt.options || {};
|
|
191
199
|
const plan = {
|
|
@@ -249,7 +257,7 @@ var convert_attempt_default = (attempt) => {
|
|
|
249
257
|
plan.jobs = Object.values(nodes);
|
|
250
258
|
return {
|
|
251
259
|
plan,
|
|
252
|
-
options
|
|
260
|
+
options: mapOptions(options)
|
|
253
261
|
};
|
|
254
262
|
};
|
|
255
263
|
|
|
@@ -298,6 +306,9 @@ var create_attempt_state_default = (plan, options = {}) => {
|
|
|
298
306
|
return state;
|
|
299
307
|
};
|
|
300
308
|
|
|
309
|
+
// src/events/run-complete.ts
|
|
310
|
+
import crypto2 from "node:crypto";
|
|
311
|
+
|
|
301
312
|
// src/api/reasons.ts
|
|
302
313
|
var calculateJobExitReason = (jobId, state = { data: {} }, error) => {
|
|
303
314
|
let reason = "success";
|
|
@@ -332,7 +343,6 @@ var calculateAttemptExitReason = (state) => {
|
|
|
332
343
|
};
|
|
333
344
|
|
|
334
345
|
// src/events/run-complete.ts
|
|
335
|
-
import crypto2 from "node:crypto";
|
|
336
346
|
function onRunComplete({ channel, state }, event, error) {
|
|
337
347
|
const dataclipId = crypto2.randomUUID();
|
|
338
348
|
const run_id = state.activeRun;
|
|
@@ -376,7 +386,7 @@ import { timestamp } from "@openfn/logger";
|
|
|
376
386
|
// package.json
|
|
377
387
|
var package_default = {
|
|
378
388
|
name: "@openfn/ws-worker",
|
|
379
|
-
version: "0.
|
|
389
|
+
version: "0.6.0",
|
|
380
390
|
description: "A Websocket Worker to connect Lightning to a Runtime Engine",
|
|
381
391
|
main: "dist/index.js",
|
|
382
392
|
type: "module",
|
|
@@ -499,6 +509,57 @@ async function onRunStart(context, event) {
|
|
|
499
509
|
return;
|
|
500
510
|
}
|
|
501
511
|
|
|
512
|
+
// src/util/log-final-reason.ts
|
|
513
|
+
import { timestamp as timestamp2 } from "@openfn/logger";
|
|
514
|
+
var log_final_reason_default = async (context, reason) => {
|
|
515
|
+
const time = (timestamp2() - BigInt(1e7)).toString();
|
|
516
|
+
let message = `Run complete with status: ${reason.reason}`;
|
|
517
|
+
if (reason.reason !== "success") {
|
|
518
|
+
message += `
|
|
519
|
+
${reason.error_type}: ${reason.error_message || "unknown"}`;
|
|
520
|
+
}
|
|
521
|
+
await onJobLog(context, {
|
|
522
|
+
time,
|
|
523
|
+
message: [message],
|
|
524
|
+
level: "info",
|
|
525
|
+
name: "R/T"
|
|
526
|
+
});
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
// src/events/attempt-complete.ts
|
|
530
|
+
async function onWorkflowComplete(context, _event) {
|
|
531
|
+
const { state, channel, onFinish } = context;
|
|
532
|
+
const result = state.dataclips[state.lastDataclipId];
|
|
533
|
+
const reason = calculateAttemptExitReason(state);
|
|
534
|
+
await log_final_reason_default(context, reason);
|
|
535
|
+
await sendEvent(channel, ATTEMPT_COMPLETE, {
|
|
536
|
+
final_dataclip_id: state.lastDataclipId,
|
|
537
|
+
...reason
|
|
538
|
+
});
|
|
539
|
+
onFinish({ reason, state: result });
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// src/events/attempt-error.ts
|
|
543
|
+
async function onAttemptError(context, event) {
|
|
544
|
+
const { state, channel, logger, onFinish } = context;
|
|
545
|
+
try {
|
|
546
|
+
const reason = calculateJobExitReason("", { data: {} }, event);
|
|
547
|
+
if (state.activeJob) {
|
|
548
|
+
await onJobError(context, { error: event });
|
|
549
|
+
}
|
|
550
|
+
await log_final_reason_default(context, reason);
|
|
551
|
+
await sendEvent(channel, ATTEMPT_COMPLETE, {
|
|
552
|
+
final_dataclip_id: state.lastDataclipId,
|
|
553
|
+
...reason
|
|
554
|
+
});
|
|
555
|
+
onFinish({ reason });
|
|
556
|
+
} catch (e) {
|
|
557
|
+
logger.error("ERROR in workflow-error handler:", e.message);
|
|
558
|
+
logger.error(e);
|
|
559
|
+
onFinish({});
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
502
563
|
// src/util/throttle.ts
|
|
503
564
|
var createThrottler = () => {
|
|
504
565
|
const q = [];
|
|
@@ -566,7 +627,7 @@ function execute(channel, engine, logger, plan, options = {}, onFinish = (_resul
|
|
|
566
627
|
addEvent("job-error", throttle(onJobError)),
|
|
567
628
|
addEvent("workflow-log", throttle(onJobLog)),
|
|
568
629
|
addEvent("workflow-complete", throttle(onWorkflowComplete)),
|
|
569
|
-
addEvent("workflow-error", throttle(
|
|
630
|
+
addEvent("workflow-error", throttle(onAttemptError))
|
|
570
631
|
);
|
|
571
632
|
engine.listen(plan.id, listeners);
|
|
572
633
|
const resolvers = {
|
|
@@ -584,7 +645,7 @@ function execute(channel, engine, logger, plan, options = {}, onFinish = (_resul
|
|
|
584
645
|
try {
|
|
585
646
|
engine.execute(plan, { resolvers, ...options });
|
|
586
647
|
} catch (e) {
|
|
587
|
-
|
|
648
|
+
onAttemptError(context, {
|
|
588
649
|
workflowId: plan.id,
|
|
589
650
|
message: e.message,
|
|
590
651
|
type: e.type,
|
|
@@ -610,33 +671,6 @@ function onJobError(context, event) {
|
|
|
610
671
|
function onWorkflowStart({ channel }, _event) {
|
|
611
672
|
return sendEvent(channel, ATTEMPT_START);
|
|
612
673
|
}
|
|
613
|
-
async function onWorkflowComplete({ state, channel, onFinish }, _event) {
|
|
614
|
-
const result = state.dataclips[state.lastDataclipId];
|
|
615
|
-
const reason = calculateAttemptExitReason(state);
|
|
616
|
-
await sendEvent(channel, ATTEMPT_COMPLETE, {
|
|
617
|
-
final_dataclip_id: state.lastDataclipId,
|
|
618
|
-
...reason
|
|
619
|
-
});
|
|
620
|
-
onFinish({ reason, state: result });
|
|
621
|
-
}
|
|
622
|
-
async function onWorkflowError(context, event) {
|
|
623
|
-
const { state, channel, logger, onFinish } = context;
|
|
624
|
-
try {
|
|
625
|
-
const reason = calculateJobExitReason("", { data: {} }, event);
|
|
626
|
-
if (state.activeJob) {
|
|
627
|
-
await onJobError(context, { error: event });
|
|
628
|
-
}
|
|
629
|
-
await sendEvent(channel, ATTEMPT_COMPLETE, {
|
|
630
|
-
final_dataclip_id: state.lastDataclipId,
|
|
631
|
-
...reason
|
|
632
|
-
});
|
|
633
|
-
onFinish({ reason });
|
|
634
|
-
} catch (e) {
|
|
635
|
-
logger.error("ERROR in workflow-error handler:", e.message);
|
|
636
|
-
logger.error(e);
|
|
637
|
-
onFinish({});
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
674
|
function onJobLog({ channel, state }, event) {
|
|
641
675
|
const timeInMicroseconds = BigInt(event.time) / BigInt(1e3);
|
|
642
676
|
const log = {
|
|
@@ -809,7 +843,6 @@ function connect(app, logger, options = {}) {
|
|
|
809
843
|
function createServer(engine, options = {}) {
|
|
810
844
|
const logger = options.logger || createMockLogger2();
|
|
811
845
|
const port = options.port || DEFAULT_PORT;
|
|
812
|
-
logger.debug("Starting server");
|
|
813
846
|
const app = new Koa();
|
|
814
847
|
app.id = humanId({ separator: "-", capitalize: false });
|
|
815
848
|
const router = new Router();
|
|
@@ -824,7 +857,7 @@ function createServer(engine, options = {}) {
|
|
|
824
857
|
app.workflows = {};
|
|
825
858
|
app.destroyed = false;
|
|
826
859
|
app.server = app.listen(port);
|
|
827
|
-
logger.success(`
|
|
860
|
+
logger.success(`Worker ${app.id} listening on ${port}`);
|
|
828
861
|
process.send?.("READY");
|
|
829
862
|
router.get("/livez", healthcheck_default);
|
|
830
863
|
router.get("/", healthcheck_default);
|
package/dist/start.js
CHANGED
|
@@ -4890,7 +4890,10 @@ var resolvers_default = {
|
|
|
4890
4890
|
// src/mock/runtime-engine.ts
|
|
4891
4891
|
var helpers = {
|
|
4892
4892
|
fn: (f) => (s) => f(s),
|
|
4893
|
-
wait: (duration) => (s) => new Promise((resolve5) => setTimeout(() => resolve5(s), duration))
|
|
4893
|
+
wait: (duration) => (s) => new Promise((resolve5) => setTimeout(() => resolve5(s), duration)),
|
|
4894
|
+
err: () => {
|
|
4895
|
+
throw new Error("test_err");
|
|
4896
|
+
}
|
|
4894
4897
|
};
|
|
4895
4898
|
async function createMock() {
|
|
4896
4899
|
const activeWorkflows = {};
|
|
@@ -5172,6 +5175,14 @@ var mapTriggerEdgeCondition = (edge) => {
|
|
|
5172
5175
|
return true;
|
|
5173
5176
|
return condition;
|
|
5174
5177
|
};
|
|
5178
|
+
var mapOptions = (options) => {
|
|
5179
|
+
const { attemptTimeout, timeout, runTimeout, ...opts } = options;
|
|
5180
|
+
const to = runTimeout || attemptTimeout || timeout;
|
|
5181
|
+
if (to) {
|
|
5182
|
+
opts.attemptTimeoutMs = to;
|
|
5183
|
+
}
|
|
5184
|
+
return opts;
|
|
5185
|
+
};
|
|
5175
5186
|
var convert_attempt_default = (attempt) => {
|
|
5176
5187
|
const options = attempt.options || {};
|
|
5177
5188
|
const plan = {
|
|
@@ -5235,7 +5246,7 @@ var convert_attempt_default = (attempt) => {
|
|
|
5235
5246
|
plan.jobs = Object.values(nodes);
|
|
5236
5247
|
return {
|
|
5237
5248
|
plan,
|
|
5238
|
-
options
|
|
5249
|
+
options: mapOptions(options)
|
|
5239
5250
|
};
|
|
5240
5251
|
};
|
|
5241
5252
|
|
|
@@ -5284,6 +5295,9 @@ var create_attempt_state_default = (plan, options = {}) => {
|
|
|
5284
5295
|
return state;
|
|
5285
5296
|
};
|
|
5286
5297
|
|
|
5298
|
+
// src/events/run-complete.ts
|
|
5299
|
+
import crypto3 from "node:crypto";
|
|
5300
|
+
|
|
5287
5301
|
// src/api/reasons.ts
|
|
5288
5302
|
var calculateJobExitReason = (jobId, state = { data: {} }, error) => {
|
|
5289
5303
|
let reason = "success";
|
|
@@ -5318,7 +5332,6 @@ var calculateAttemptExitReason = (state) => {
|
|
|
5318
5332
|
};
|
|
5319
5333
|
|
|
5320
5334
|
// src/events/run-complete.ts
|
|
5321
|
-
import crypto3 from "node:crypto";
|
|
5322
5335
|
function onRunComplete({ channel, state }, event, error) {
|
|
5323
5336
|
const dataclipId = crypto3.randomUUID();
|
|
5324
5337
|
const run_id = state.activeRun;
|
|
@@ -5362,7 +5375,7 @@ import { timestamp } from "@openfn/logger";
|
|
|
5362
5375
|
// package.json
|
|
5363
5376
|
var package_default = {
|
|
5364
5377
|
name: "@openfn/ws-worker",
|
|
5365
|
-
version: "0.
|
|
5378
|
+
version: "0.6.0",
|
|
5366
5379
|
description: "A Websocket Worker to connect Lightning to a Runtime Engine",
|
|
5367
5380
|
main: "dist/index.js",
|
|
5368
5381
|
type: "module",
|
|
@@ -5485,6 +5498,57 @@ async function onRunStart(context, event) {
|
|
|
5485
5498
|
return;
|
|
5486
5499
|
}
|
|
5487
5500
|
|
|
5501
|
+
// src/util/log-final-reason.ts
|
|
5502
|
+
import { timestamp as timestamp2 } from "@openfn/logger";
|
|
5503
|
+
var log_final_reason_default = async (context, reason) => {
|
|
5504
|
+
const time = (timestamp2() - BigInt(1e7)).toString();
|
|
5505
|
+
let message = `Run complete with status: ${reason.reason}`;
|
|
5506
|
+
if (reason.reason !== "success") {
|
|
5507
|
+
message += `
|
|
5508
|
+
${reason.error_type}: ${reason.error_message || "unknown"}`;
|
|
5509
|
+
}
|
|
5510
|
+
await onJobLog(context, {
|
|
5511
|
+
time,
|
|
5512
|
+
message: [message],
|
|
5513
|
+
level: "info",
|
|
5514
|
+
name: "R/T"
|
|
5515
|
+
});
|
|
5516
|
+
};
|
|
5517
|
+
|
|
5518
|
+
// src/events/attempt-complete.ts
|
|
5519
|
+
async function onWorkflowComplete(context, _event) {
|
|
5520
|
+
const { state, channel, onFinish } = context;
|
|
5521
|
+
const result = state.dataclips[state.lastDataclipId];
|
|
5522
|
+
const reason = calculateAttemptExitReason(state);
|
|
5523
|
+
await log_final_reason_default(context, reason);
|
|
5524
|
+
await sendEvent(channel, ATTEMPT_COMPLETE, {
|
|
5525
|
+
final_dataclip_id: state.lastDataclipId,
|
|
5526
|
+
...reason
|
|
5527
|
+
});
|
|
5528
|
+
onFinish({ reason, state: result });
|
|
5529
|
+
}
|
|
5530
|
+
|
|
5531
|
+
// src/events/attempt-error.ts
|
|
5532
|
+
async function onAttemptError(context, event) {
|
|
5533
|
+
const { state, channel, logger: logger2, onFinish } = context;
|
|
5534
|
+
try {
|
|
5535
|
+
const reason = calculateJobExitReason("", { data: {} }, event);
|
|
5536
|
+
if (state.activeJob) {
|
|
5537
|
+
await onJobError(context, { error: event });
|
|
5538
|
+
}
|
|
5539
|
+
await log_final_reason_default(context, reason);
|
|
5540
|
+
await sendEvent(channel, ATTEMPT_COMPLETE, {
|
|
5541
|
+
final_dataclip_id: state.lastDataclipId,
|
|
5542
|
+
...reason
|
|
5543
|
+
});
|
|
5544
|
+
onFinish({ reason });
|
|
5545
|
+
} catch (e) {
|
|
5546
|
+
logger2.error("ERROR in workflow-error handler:", e.message);
|
|
5547
|
+
logger2.error(e);
|
|
5548
|
+
onFinish({});
|
|
5549
|
+
}
|
|
5550
|
+
}
|
|
5551
|
+
|
|
5488
5552
|
// src/util/throttle.ts
|
|
5489
5553
|
var createThrottler = () => {
|
|
5490
5554
|
const q = [];
|
|
@@ -5552,7 +5616,7 @@ function execute(channel, engine, logger2, plan, options = {}, onFinish = (_resu
|
|
|
5552
5616
|
addEvent("job-error", throttle(onJobError)),
|
|
5553
5617
|
addEvent("workflow-log", throttle(onJobLog)),
|
|
5554
5618
|
addEvent("workflow-complete", throttle(onWorkflowComplete)),
|
|
5555
|
-
addEvent("workflow-error", throttle(
|
|
5619
|
+
addEvent("workflow-error", throttle(onAttemptError))
|
|
5556
5620
|
);
|
|
5557
5621
|
engine.listen(plan.id, listeners);
|
|
5558
5622
|
const resolvers = {
|
|
@@ -5570,7 +5634,7 @@ function execute(channel, engine, logger2, plan, options = {}, onFinish = (_resu
|
|
|
5570
5634
|
try {
|
|
5571
5635
|
engine.execute(plan, { resolvers, ...options });
|
|
5572
5636
|
} catch (e) {
|
|
5573
|
-
|
|
5637
|
+
onAttemptError(context, {
|
|
5574
5638
|
workflowId: plan.id,
|
|
5575
5639
|
message: e.message,
|
|
5576
5640
|
type: e.type,
|
|
@@ -5596,33 +5660,6 @@ function onJobError(context, event) {
|
|
|
5596
5660
|
function onWorkflowStart({ channel }, _event) {
|
|
5597
5661
|
return sendEvent(channel, ATTEMPT_START);
|
|
5598
5662
|
}
|
|
5599
|
-
async function onWorkflowComplete({ state, channel, onFinish }, _event) {
|
|
5600
|
-
const result = state.dataclips[state.lastDataclipId];
|
|
5601
|
-
const reason = calculateAttemptExitReason(state);
|
|
5602
|
-
await sendEvent(channel, ATTEMPT_COMPLETE, {
|
|
5603
|
-
final_dataclip_id: state.lastDataclipId,
|
|
5604
|
-
...reason
|
|
5605
|
-
});
|
|
5606
|
-
onFinish({ reason, state: result });
|
|
5607
|
-
}
|
|
5608
|
-
async function onWorkflowError(context, event) {
|
|
5609
|
-
const { state, channel, logger: logger2, onFinish } = context;
|
|
5610
|
-
try {
|
|
5611
|
-
const reason = calculateJobExitReason("", { data: {} }, event);
|
|
5612
|
-
if (state.activeJob) {
|
|
5613
|
-
await onJobError(context, { error: event });
|
|
5614
|
-
}
|
|
5615
|
-
await sendEvent(channel, ATTEMPT_COMPLETE, {
|
|
5616
|
-
final_dataclip_id: state.lastDataclipId,
|
|
5617
|
-
...reason
|
|
5618
|
-
});
|
|
5619
|
-
onFinish({ reason });
|
|
5620
|
-
} catch (e) {
|
|
5621
|
-
logger2.error("ERROR in workflow-error handler:", e.message);
|
|
5622
|
-
logger2.error(e);
|
|
5623
|
-
onFinish({});
|
|
5624
|
-
}
|
|
5625
|
-
}
|
|
5626
5663
|
function onJobLog({ channel, state }, event) {
|
|
5627
5664
|
const timeInMicroseconds = BigInt(event.time) / BigInt(1e3);
|
|
5628
5665
|
const log = {
|
|
@@ -5795,7 +5832,6 @@ function connect(app, logger2, options = {}) {
|
|
|
5795
5832
|
function createServer(engine, options = {}) {
|
|
5796
5833
|
const logger2 = options.logger || createMockLogger2();
|
|
5797
5834
|
const port = options.port || DEFAULT_PORT;
|
|
5798
|
-
logger2.debug("Starting server");
|
|
5799
5835
|
const app = new Koa();
|
|
5800
5836
|
app.id = humanId({ separator: "-", capitalize: false });
|
|
5801
5837
|
const router = new Router();
|
|
@@ -5810,7 +5846,7 @@ function createServer(engine, options = {}) {
|
|
|
5810
5846
|
app.workflows = {};
|
|
5811
5847
|
app.destroyed = false;
|
|
5812
5848
|
app.server = app.listen(port);
|
|
5813
|
-
logger2.success(`
|
|
5849
|
+
logger2.success(`Worker ${app.id} listening on ${port}`);
|
|
5814
5850
|
process.send?.("READY");
|
|
5815
5851
|
router.get("/livez", healthcheck_default);
|
|
5816
5852
|
router.get("/", healthcheck_default);
|
|
@@ -5879,30 +5915,37 @@ var server_default = createServer;
|
|
|
5879
5915
|
|
|
5880
5916
|
// src/start.ts
|
|
5881
5917
|
var {
|
|
5918
|
+
WORKER_BACKOFF,
|
|
5919
|
+
WORKER_CAPACITY,
|
|
5920
|
+
WORKER_LIGHTNING_SERVICE_URL,
|
|
5921
|
+
WORKER_LOG_LEVEL,
|
|
5922
|
+
WORKER_MAX_RUN_DURATION_SECONDS,
|
|
5923
|
+
WORKER_MAX_RUN_MEMORY_MB,
|
|
5924
|
+
WORKER_PORT,
|
|
5882
5925
|
WORKER_REPO_DIR,
|
|
5883
5926
|
WORKER_SECRET,
|
|
5884
|
-
|
|
5885
|
-
STATE_PROPS_TO_REMOVE
|
|
5927
|
+
WORKER_STATE_PROPS_TO_REMOVE
|
|
5886
5928
|
} = process.env;
|
|
5887
5929
|
var args = yargs_default(hideBin(process.argv)).command("server", "Start a ws-worker server").option("port", {
|
|
5888
5930
|
alias: "p",
|
|
5889
|
-
description: "Port to run the server on",
|
|
5931
|
+
description: "Port to run the server on. Env: WORKER_PORT",
|
|
5890
5932
|
type: "number",
|
|
5891
|
-
default: 2222
|
|
5933
|
+
default: WORKER_PORT || 2222
|
|
5892
5934
|
}).option("lightning", {
|
|
5893
|
-
alias: "l",
|
|
5894
|
-
description: 'Base url to Lightning websocket endpoint, eg, ws://localhost:4000/worker. Set to "mock" to use the default mock server',
|
|
5895
|
-
default: "ws://localhost:4000/worker"
|
|
5935
|
+
alias: ["l", "lightning-service-url"],
|
|
5936
|
+
description: 'Base url to Lightning websocket endpoint, eg, ws://localhost:4000/worker. Set to "mock" to use the default mock server. Env: WORKER_LIGHTNING_SERVICE_URL',
|
|
5937
|
+
default: WORKER_LIGHTNING_SERVICE_URL || "ws://localhost:4000/worker"
|
|
5896
5938
|
}).option("repo-dir", {
|
|
5897
5939
|
alias: "d",
|
|
5898
|
-
description: "Path to the runtime repo (where modules will be installed)",
|
|
5940
|
+
description: "Path to the runtime repo (where modules will be installed). Env: WORKER_REPO_DIR",
|
|
5899
5941
|
default: WORKER_REPO_DIR
|
|
5900
5942
|
}).option("secret", {
|
|
5901
5943
|
alias: "s",
|
|
5902
|
-
description: "Worker secret (comes from WORKER_SECRET by default)"
|
|
5944
|
+
description: "Worker secret. (comes from WORKER_SECRET by default). Env: WORKER_SECRET",
|
|
5945
|
+
default: WORKER_SECRET
|
|
5903
5946
|
}).option("log", {
|
|
5904
|
-
description: "
|
|
5905
|
-
default: "
|
|
5947
|
+
description: "Set the log level for stdout (default to info, set to debug for verbose output). Env: WORKER_LOG_LEVEL",
|
|
5948
|
+
default: WORKER_LOG_LEVEL || "debug",
|
|
5906
5949
|
type: "string"
|
|
5907
5950
|
}).option("loop", {
|
|
5908
5951
|
description: "Disable the claims loop",
|
|
@@ -5913,20 +5956,25 @@ var args = yargs_default(hideBin(process.argv)).command("server", "Start a ws-wo
|
|
|
5913
5956
|
default: false,
|
|
5914
5957
|
type: "boolean"
|
|
5915
5958
|
}).option("backoff", {
|
|
5916
|
-
description: "Claim backoff rules: min/max (
|
|
5917
|
-
default: "1/10"
|
|
5959
|
+
description: "Claim backoff rules: min/max (in seconds). Env: WORKER_BACKOFF",
|
|
5960
|
+
default: WORKER_BACKOFF || "1/10"
|
|
5918
5961
|
}).option("capacity", {
|
|
5919
|
-
description: "max concurrent workers",
|
|
5920
|
-
default: 5,
|
|
5962
|
+
description: "max concurrent workers. Env: WORKER_CAPACITY",
|
|
5963
|
+
default: WORKER_CAPACITY ? parseInt(WORKER_CAPACITY) : 5,
|
|
5921
5964
|
type: "number"
|
|
5922
5965
|
}).option("state-props-to-remove", {
|
|
5923
|
-
description: "A list of properties to remove from the final state returned by a job",
|
|
5924
|
-
default:
|
|
5966
|
+
description: "A list of properties to remove from the final state returned by a job. Env: WORKER_STATE_PROPS_TO_REMOVE",
|
|
5967
|
+
default: WORKER_STATE_PROPS_TO_REMOVE ?? ["configuration", "response"],
|
|
5925
5968
|
type: "array"
|
|
5926
5969
|
}).option("run-memory", {
|
|
5927
|
-
description: "Maximum memory allocated to a single run, in mb",
|
|
5970
|
+
description: "Maximum memory allocated to a single run, in mb. Env: WORKER_MAX_RUN_MEMORY_MB",
|
|
5971
|
+
type: "number",
|
|
5972
|
+
default: WORKER_MAX_RUN_MEMORY_MB ? parseInt(WORKER_MAX_RUN_MEMORY_MB) : 500
|
|
5973
|
+
}).option("max-run-duration-seconds", {
|
|
5974
|
+
alias: "t",
|
|
5975
|
+
description: "Default attempt timeout for the server, in seconds. Env: WORKER_MAX_RUN_DURATION_SECONDS",
|
|
5928
5976
|
type: "number",
|
|
5929
|
-
default:
|
|
5977
|
+
default: WORKER_MAX_RUN_DURATION_SECONDS || 60 * 5
|
|
5930
5978
|
}).parse();
|
|
5931
5979
|
var logger = createLogger("SRV", { level: args.log });
|
|
5932
5980
|
if (args.lightning === "mock") {
|
|
@@ -5935,15 +5983,13 @@ if (args.lightning === "mock") {
|
|
|
5935
5983
|
args.secret = "abdefg";
|
|
5936
5984
|
}
|
|
5937
5985
|
} else if (!args.secret) {
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
process.exit(1);
|
|
5941
|
-
}
|
|
5942
|
-
args.secret = WORKER_SECRET;
|
|
5986
|
+
logger.error("WORKER_SECRET is not set");
|
|
5987
|
+
process.exit(1);
|
|
5943
5988
|
}
|
|
5944
5989
|
var [minBackoff, maxBackoff] = args.backoff.split("/").map((n) => parseInt(n, 10) * 1e3);
|
|
5945
5990
|
function engineReady(engine) {
|
|
5946
|
-
|
|
5991
|
+
logger.debug("Creating worker server...");
|
|
5992
|
+
const workerOptions = {
|
|
5947
5993
|
port: args.port,
|
|
5948
5994
|
lightning: args.lightning,
|
|
5949
5995
|
logger,
|
|
@@ -5954,7 +6000,10 @@ function engineReady(engine) {
|
|
|
5954
6000
|
max: maxBackoff
|
|
5955
6001
|
},
|
|
5956
6002
|
maxWorkflows: args.capacity
|
|
5957
|
-
}
|
|
6003
|
+
};
|
|
6004
|
+
const { logger: _l, secret: _s, ...humanOptions } = workerOptions;
|
|
6005
|
+
logger.debug("Worker options:", humanOptions);
|
|
6006
|
+
server_default(engine, workerOptions);
|
|
5958
6007
|
}
|
|
5959
6008
|
if (args.mock) {
|
|
5960
6009
|
runtime_engine_default().then((engine) => {
|
|
@@ -5962,13 +6011,17 @@ if (args.mock) {
|
|
|
5962
6011
|
engineReady(engine);
|
|
5963
6012
|
});
|
|
5964
6013
|
} else {
|
|
5965
|
-
|
|
6014
|
+
const engineOptions = {
|
|
5966
6015
|
repoDir: args.repoDir,
|
|
5967
6016
|
memoryLimitMb: args.runMemory,
|
|
5968
6017
|
maxWorkers: args.capacity,
|
|
5969
|
-
statePropsToRemove: args.statePropsToRemove
|
|
5970
|
-
|
|
5971
|
-
|
|
6018
|
+
statePropsToRemove: args.statePropsToRemove,
|
|
6019
|
+
attemptTimeoutMs: args.maxRunDurationSeconds * 1e3
|
|
6020
|
+
};
|
|
6021
|
+
logger.debug("Creating runtime engine...");
|
|
6022
|
+
logger.debug("Engine options:", engineOptions);
|
|
6023
|
+
createRTE(engineOptions).then((engine) => {
|
|
6024
|
+
logger.debug("Engine created!");
|
|
5972
6025
|
engineReady(engine);
|
|
5973
6026
|
});
|
|
5974
6027
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/ws-worker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "A Websocket Worker to connect Lightning to a Runtime Engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"koa-logger": "^3.2.1",
|
|
23
23
|
"phoenix": "^1.7.7",
|
|
24
24
|
"ws": "^8.14.1",
|
|
25
|
-
"@openfn/engine-multi": "0.
|
|
26
|
-
"@openfn/
|
|
27
|
-
"@openfn/
|
|
25
|
+
"@openfn/engine-multi": "0.3.0",
|
|
26
|
+
"@openfn/logger": "0.0.19",
|
|
27
|
+
"@openfn/runtime": "0.2.5"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/koa": "^2.13.5",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"tsup": "^6.2.3",
|
|
42
42
|
"typescript": "^4.6.4",
|
|
43
43
|
"yargs": "^17.6.2",
|
|
44
|
-
"@openfn/lightning-mock": "1.1.
|
|
44
|
+
"@openfn/lightning-mock": "1.1.10"
|
|
45
45
|
},
|
|
46
46
|
"files": [
|
|
47
47
|
"dist",
|