@openfn/ws-worker 0.2.10 → 0.2.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.
- package/CHANGELOG.md +20 -0
- package/dist/index.js +13 -5
- package/dist/start.js +37 -15
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# ws-worker
|
|
2
2
|
|
|
3
|
+
## 0.2.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6c3e9e42: Ensure capacity is also set on the engine
|
|
8
|
+
- Updated dependencies [05ccc10b]
|
|
9
|
+
- Updated dependencies [7235bf5e]
|
|
10
|
+
- @openfn/engine-multi@0.2.3
|
|
11
|
+
|
|
12
|
+
## 0.2.11
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 22339c6: Add MAX_RUN_MEMORY env var and option to limit the memory available to each run
|
|
17
|
+
- 04ac3cc: Include duration and threadid in run-complete
|
|
18
|
+
- 340b96e: Send memory usage to lightning on run:complete
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
- @openfn/engine-multi@0.2.2
|
|
21
|
+
- @openfn/runtime@0.2.1
|
|
22
|
+
|
|
3
23
|
## 0.2.10
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -409,7 +409,7 @@ function onJobStart({ channel, state }, event) {
|
|
|
409
409
|
});
|
|
410
410
|
}
|
|
411
411
|
function onJobError(context, event) {
|
|
412
|
-
const { state, error, jobId } = event;
|
|
412
|
+
const { state = {}, error, jobId } = event;
|
|
413
413
|
if (state.errors?.[jobId]?.message === error.message) {
|
|
414
414
|
onJobComplete(context, event);
|
|
415
415
|
} else {
|
|
@@ -424,12 +424,12 @@ function onJobComplete({ channel, state }, event, error) {
|
|
|
424
424
|
state.dataclips = {};
|
|
425
425
|
}
|
|
426
426
|
state.dataclips[dataclipId] = event.state;
|
|
427
|
+
delete state.activeRun;
|
|
428
|
+
delete state.activeJob;
|
|
427
429
|
state.lastDataclipId = dataclipId;
|
|
428
430
|
event.next?.forEach((nextJobId) => {
|
|
429
431
|
state.inputDataclips[nextJobId] = dataclipId;
|
|
430
432
|
});
|
|
431
|
-
delete state.activeRun;
|
|
432
|
-
delete state.activeJob;
|
|
433
433
|
const { reason, error_message, error_type } = calculateJobExitReason(
|
|
434
434
|
job_id,
|
|
435
435
|
event.state,
|
|
@@ -443,7 +443,10 @@ function onJobComplete({ channel, state }, event, error) {
|
|
|
443
443
|
output_dataclip: stringify_default(event.state),
|
|
444
444
|
reason,
|
|
445
445
|
error_message,
|
|
446
|
-
error_type
|
|
446
|
+
error_type,
|
|
447
|
+
mem: event.mem,
|
|
448
|
+
duration: event.duration,
|
|
449
|
+
thread_id: event.threadId
|
|
447
450
|
};
|
|
448
451
|
return sendEvent(channel, RUN_COMPLETE, evt);
|
|
449
452
|
}
|
|
@@ -459,9 +462,13 @@ async function onWorkflowComplete({ state, channel, onFinish }, _event) {
|
|
|
459
462
|
});
|
|
460
463
|
onFinish({ reason, state: result });
|
|
461
464
|
}
|
|
462
|
-
async function onWorkflowError(
|
|
465
|
+
async function onWorkflowError(context, event) {
|
|
466
|
+
const { state, channel, logger, onFinish } = context;
|
|
463
467
|
try {
|
|
464
468
|
const reason = calculateJobExitReason("", { data: {} }, event);
|
|
469
|
+
if (state.activeJob) {
|
|
470
|
+
await onJobError(context, { error: event });
|
|
471
|
+
}
|
|
465
472
|
await sendEvent(channel, ATTEMPT_COMPLETE, {
|
|
466
473
|
final_dataclip_id: state.lastDataclipId,
|
|
467
474
|
...reason
|
|
@@ -470,6 +477,7 @@ async function onWorkflowError({ state, channel, logger, onFinish }, event) {
|
|
|
470
477
|
} catch (e) {
|
|
471
478
|
logger.error("ERROR in workflow-error handler:", e.message);
|
|
472
479
|
logger.error(e);
|
|
480
|
+
onFinish({});
|
|
473
481
|
}
|
|
474
482
|
}
|
|
475
483
|
function onJobLog({ channel, state }, event) {
|
package/dist/start.js
CHANGED
|
@@ -4865,6 +4865,7 @@ import createRTE from "@openfn/engine-multi";
|
|
|
4865
4865
|
|
|
4866
4866
|
// src/mock/runtime-engine.ts
|
|
4867
4867
|
import { EventEmitter } from "node:events";
|
|
4868
|
+
import crypto from "node:crypto";
|
|
4868
4869
|
import run from "@openfn/runtime";
|
|
4869
4870
|
|
|
4870
4871
|
// src/mock/resolvers.ts
|
|
@@ -4911,6 +4912,7 @@ async function createMock() {
|
|
|
4911
4912
|
}) => {
|
|
4912
4913
|
const { id, jobs } = xplan;
|
|
4913
4914
|
activeWorkflows[id] = true;
|
|
4915
|
+
const threadId = crypto.randomUUID();
|
|
4914
4916
|
for (const job of jobs) {
|
|
4915
4917
|
if (typeof job.configuration === "string") {
|
|
4916
4918
|
job.configuration = await options.resolvers?.credential?.(
|
|
@@ -4925,6 +4927,7 @@ async function createMock() {
|
|
|
4925
4927
|
log: (...args2) => {
|
|
4926
4928
|
dispatch("workflow-log", {
|
|
4927
4929
|
workflowId: id,
|
|
4930
|
+
threadId,
|
|
4928
4931
|
level: "info",
|
|
4929
4932
|
json: true,
|
|
4930
4933
|
message: args2,
|
|
@@ -4941,24 +4944,27 @@ async function createMock() {
|
|
|
4941
4944
|
notify: (name, payload) => {
|
|
4942
4945
|
dispatch(name, {
|
|
4943
4946
|
workflowId: id,
|
|
4947
|
+
threadId,
|
|
4944
4948
|
...payload
|
|
4945
4949
|
});
|
|
4946
4950
|
}
|
|
4947
4951
|
}
|
|
4948
4952
|
};
|
|
4949
4953
|
setTimeout(async () => {
|
|
4950
|
-
dispatch("workflow-start", { workflowId: id });
|
|
4954
|
+
dispatch("workflow-start", { workflowId: id, threadId });
|
|
4951
4955
|
try {
|
|
4952
4956
|
await run(xplan, void 0, opts);
|
|
4957
|
+
dispatch("workflow-complete", { workflowId: id, threadId });
|
|
4953
4958
|
} catch (e) {
|
|
4954
4959
|
dispatch("workflow-error", {
|
|
4960
|
+
threadId,
|
|
4955
4961
|
workflowId: id,
|
|
4956
4962
|
type: e.name,
|
|
4957
4963
|
message: e.message
|
|
4958
4964
|
});
|
|
4965
|
+
} finally {
|
|
4966
|
+
delete activeWorkflows[id];
|
|
4959
4967
|
}
|
|
4960
|
-
delete activeWorkflows[id];
|
|
4961
|
-
dispatch("workflow-complete", { workflowId: id });
|
|
4962
4968
|
}, 1);
|
|
4963
4969
|
};
|
|
4964
4970
|
const getStatus = () => {
|
|
@@ -5146,10 +5152,10 @@ var startWorkloop = (app, logger2, minBackoff2, maxBackoff2, maxWorkers) => {
|
|
|
5146
5152
|
var workloop_default = startWorkloop;
|
|
5147
5153
|
|
|
5148
5154
|
// src/api/execute.ts
|
|
5149
|
-
import
|
|
5155
|
+
import crypto3 from "node:crypto";
|
|
5150
5156
|
|
|
5151
5157
|
// src/util/convert-attempt.ts
|
|
5152
|
-
import
|
|
5158
|
+
import crypto2 from "node:crypto";
|
|
5153
5159
|
var conditions = {
|
|
5154
5160
|
on_job_success: (upstreamId) => `Boolean(!state.errors?.["${upstreamId}"] ?? true)`,
|
|
5155
5161
|
on_job_failure: (upstreamId) => `Boolean(state.errors && state.errors["${upstreamId}"])`,
|
|
@@ -5196,7 +5202,7 @@ var convert_attempt_default = (attempt) => {
|
|
|
5196
5202
|
}
|
|
5197
5203
|
if (attempt.jobs?.length) {
|
|
5198
5204
|
attempt.jobs.forEach((job) => {
|
|
5199
|
-
const id = job.id ||
|
|
5205
|
+
const id = job.id || crypto2.randomUUID();
|
|
5200
5206
|
nodes[id] = {
|
|
5201
5207
|
id,
|
|
5202
5208
|
configuration: job.credential_id,
|
|
@@ -5379,7 +5385,7 @@ var sendEvent = (channel, event, payload) => new Promise((resolve5, reject) => {
|
|
|
5379
5385
|
channel.push(event, payload).receive("error", reject).receive("timeout", () => reject(new Error("timeout"))).receive("ok", resolve5);
|
|
5380
5386
|
});
|
|
5381
5387
|
function onJobStart({ channel, state }, event) {
|
|
5382
|
-
state.activeRun =
|
|
5388
|
+
state.activeRun = crypto3.randomUUID();
|
|
5383
5389
|
state.activeJob = event.jobId;
|
|
5384
5390
|
const input_dataclip_id = state.inputDataclips[event.jobId];
|
|
5385
5391
|
return sendEvent(channel, RUN_START, {
|
|
@@ -5389,7 +5395,7 @@ function onJobStart({ channel, state }, event) {
|
|
|
5389
5395
|
});
|
|
5390
5396
|
}
|
|
5391
5397
|
function onJobError(context, event) {
|
|
5392
|
-
const { state, error, jobId } = event;
|
|
5398
|
+
const { state = {}, error, jobId } = event;
|
|
5393
5399
|
if (state.errors?.[jobId]?.message === error.message) {
|
|
5394
5400
|
onJobComplete(context, event);
|
|
5395
5401
|
} else {
|
|
@@ -5397,19 +5403,19 @@ function onJobError(context, event) {
|
|
|
5397
5403
|
}
|
|
5398
5404
|
}
|
|
5399
5405
|
function onJobComplete({ channel, state }, event, error) {
|
|
5400
|
-
const dataclipId =
|
|
5406
|
+
const dataclipId = crypto3.randomUUID();
|
|
5401
5407
|
const run_id = state.activeRun;
|
|
5402
5408
|
const job_id = state.activeJob;
|
|
5403
5409
|
if (!state.dataclips) {
|
|
5404
5410
|
state.dataclips = {};
|
|
5405
5411
|
}
|
|
5406
5412
|
state.dataclips[dataclipId] = event.state;
|
|
5413
|
+
delete state.activeRun;
|
|
5414
|
+
delete state.activeJob;
|
|
5407
5415
|
state.lastDataclipId = dataclipId;
|
|
5408
5416
|
event.next?.forEach((nextJobId) => {
|
|
5409
5417
|
state.inputDataclips[nextJobId] = dataclipId;
|
|
5410
5418
|
});
|
|
5411
|
-
delete state.activeRun;
|
|
5412
|
-
delete state.activeJob;
|
|
5413
5419
|
const { reason, error_message, error_type } = calculateJobExitReason(
|
|
5414
5420
|
job_id,
|
|
5415
5421
|
event.state,
|
|
@@ -5423,7 +5429,10 @@ function onJobComplete({ channel, state }, event, error) {
|
|
|
5423
5429
|
output_dataclip: stringify_default(event.state),
|
|
5424
5430
|
reason,
|
|
5425
5431
|
error_message,
|
|
5426
|
-
error_type
|
|
5432
|
+
error_type,
|
|
5433
|
+
mem: event.mem,
|
|
5434
|
+
duration: event.duration,
|
|
5435
|
+
thread_id: event.threadId
|
|
5427
5436
|
};
|
|
5428
5437
|
return sendEvent(channel, RUN_COMPLETE, evt);
|
|
5429
5438
|
}
|
|
@@ -5439,9 +5448,13 @@ async function onWorkflowComplete({ state, channel, onFinish }, _event) {
|
|
|
5439
5448
|
});
|
|
5440
5449
|
onFinish({ reason, state: result });
|
|
5441
5450
|
}
|
|
5442
|
-
async function onWorkflowError(
|
|
5451
|
+
async function onWorkflowError(context, event) {
|
|
5452
|
+
const { state, channel, logger: logger2, onFinish } = context;
|
|
5443
5453
|
try {
|
|
5444
5454
|
const reason = calculateJobExitReason("", { data: {} }, event);
|
|
5455
|
+
if (state.activeJob) {
|
|
5456
|
+
await onJobError(context, { error: event });
|
|
5457
|
+
}
|
|
5445
5458
|
await sendEvent(channel, ATTEMPT_COMPLETE, {
|
|
5446
5459
|
final_dataclip_id: state.lastDataclipId,
|
|
5447
5460
|
...reason
|
|
@@ -5450,6 +5463,7 @@ async function onWorkflowError({ state, channel, logger: logger2, onFinish }, ev
|
|
|
5450
5463
|
} catch (e) {
|
|
5451
5464
|
logger2.error("ERROR in workflow-error handler:", e.message);
|
|
5452
5465
|
logger2.error(e);
|
|
5466
|
+
onFinish({});
|
|
5453
5467
|
}
|
|
5454
5468
|
}
|
|
5455
5469
|
function onJobLog({ channel, state }, event) {
|
|
@@ -5707,7 +5721,7 @@ function createServer(engine, options = {}) {
|
|
|
5707
5721
|
var server_default = createServer;
|
|
5708
5722
|
|
|
5709
5723
|
// src/start.ts
|
|
5710
|
-
var { WORKER_REPO_DIR, WORKER_SECRET } = process.env;
|
|
5724
|
+
var { WORKER_REPO_DIR, WORKER_SECRET, MAX_RUN_MEMORY } = process.env;
|
|
5711
5725
|
var args = yargs_default(hideBin(process.argv)).command("server", "Start a ws-worker server").option("port", {
|
|
5712
5726
|
alias: "p",
|
|
5713
5727
|
description: "Port to run the server on",
|
|
@@ -5743,6 +5757,10 @@ var args = yargs_default(hideBin(process.argv)).command("server", "Start a ws-wo
|
|
|
5743
5757
|
description: "max concurrent workers",
|
|
5744
5758
|
default: 5,
|
|
5745
5759
|
type: "number"
|
|
5760
|
+
}).option("run-memory", {
|
|
5761
|
+
description: "Maximum memory allocated to a single run, in mb",
|
|
5762
|
+
type: "number",
|
|
5763
|
+
default: MAX_RUN_MEMORY ? parseInt(MAX_RUN_MEMORY) : 500
|
|
5746
5764
|
}).parse();
|
|
5747
5765
|
var logger = createLogger("SRV", { level: args.log });
|
|
5748
5766
|
if (args.lightning === "mock") {
|
|
@@ -5778,7 +5796,11 @@ if (args.mock) {
|
|
|
5778
5796
|
engineReady(engine);
|
|
5779
5797
|
});
|
|
5780
5798
|
} else {
|
|
5781
|
-
createRTE({
|
|
5799
|
+
createRTE({
|
|
5800
|
+
repoDir: args.repoDir,
|
|
5801
|
+
memoryLimitMb: args.runMemory,
|
|
5802
|
+
maxWorkers: args.capacity
|
|
5803
|
+
}).then((engine) => {
|
|
5782
5804
|
logger.debug("engine created");
|
|
5783
5805
|
engineReady(engine);
|
|
5784
5806
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/ws-worker",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
4
4
|
"description": "A Websocket Worker to connect Lightning to a Runtime Engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"koa-logger": "^3.2.1",
|
|
22
22
|
"phoenix": "^1.7.7",
|
|
23
23
|
"ws": "^8.14.1",
|
|
24
|
-
"@openfn/engine-multi": "0.2.
|
|
24
|
+
"@openfn/engine-multi": "0.2.3",
|
|
25
25
|
"@openfn/logger": "0.0.19",
|
|
26
|
-
"@openfn/runtime": "0.2.
|
|
26
|
+
"@openfn/runtime": "0.2.1"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/koa": "^2.13.5",
|
|
@@ -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.1.
|
|
43
|
+
"@openfn/lightning-mock": "1.1.5"
|
|
44
44
|
},
|
|
45
45
|
"files": [
|
|
46
46
|
"dist",
|