@openfn/ws-worker 1.6.6 → 1.7.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 +17 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +38 -29
- package/dist/start.js +38 -29
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# ws-worker
|
|
2
2
|
|
|
3
|
+
## 1.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ae55a6a: Include timestamp on step complete even if the step failed
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [ae55a6a]
|
|
12
|
+
- @openfn/engine-multi@1.3.0
|
|
13
|
+
|
|
14
|
+
## 1.6.7
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 42883f8: Better handliung of claim backoffs when at capacity
|
|
19
|
+
|
|
3
20
|
## 1.6.6
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,11 @@ import { ExecutionPlan, Lazy, State } from '@openfn/lexicon';
|
|
|
8
8
|
import { Channel as Channel$1 } from 'phoenix';
|
|
9
9
|
import { Server } from 'http';
|
|
10
10
|
|
|
11
|
+
declare type Workloop = {
|
|
12
|
+
stop: (reason?: string) => void;
|
|
13
|
+
isStopped: () => boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
11
16
|
// Internal server state for each run
|
|
12
17
|
type RunState = {
|
|
13
18
|
activeStep?: string;
|
|
@@ -80,9 +85,10 @@ interface ServerApp extends Koa {
|
|
|
80
85
|
server: Server;
|
|
81
86
|
engine: RuntimeEngine;
|
|
82
87
|
options: ServerOptions;
|
|
88
|
+
workloop?: Workloop;
|
|
83
89
|
execute: ({ id, token }: ClaimRun) => Promise<void>;
|
|
84
90
|
destroy: () => void;
|
|
85
|
-
|
|
91
|
+
resumeWorkloop: () => void;
|
|
86
92
|
}
|
|
87
93
|
declare function createServer(engine: RuntimeEngine, options?: ServerOptions): ServerApp;
|
|
88
94
|
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ var name, version, description, main, type, scripts, bin, author, license, depen
|
|
|
29
29
|
var init_package = __esm({
|
|
30
30
|
"package.json"() {
|
|
31
31
|
name = "@openfn/ws-worker";
|
|
32
|
-
version = "1.
|
|
32
|
+
version = "1.7.0";
|
|
33
33
|
description = "A Websocket Worker to connect Lightning to a Runtime Engine";
|
|
34
34
|
main = "dist/index.js";
|
|
35
35
|
type = "module";
|
|
@@ -132,7 +132,7 @@ var destroy = async (app, logger) => {
|
|
|
132
132
|
await Promise.all([
|
|
133
133
|
new Promise((resolve) => {
|
|
134
134
|
app.destroyed = true;
|
|
135
|
-
app.
|
|
135
|
+
app.workloop?.stop("server closed");
|
|
136
136
|
app.queueChannel?.leave();
|
|
137
137
|
app.server.close(async () => {
|
|
138
138
|
resolve();
|
|
@@ -232,9 +232,7 @@ var claim = (app, logger = mockLogger, options = {}) => {
|
|
|
232
232
|
const { maxWorkers = 5 } = options;
|
|
233
233
|
const activeWorkers = Object.keys(app.workflows).length;
|
|
234
234
|
if (activeWorkers >= maxWorkers) {
|
|
235
|
-
|
|
236
|
-
`skipping claim attempt: server at capacity (${activeWorkers}/${maxWorkers})`
|
|
237
|
-
);
|
|
235
|
+
app.workloop?.stop(`server at capacity (${activeWorkers}/${maxWorkers})`);
|
|
238
236
|
return reject(new Error("Server at capacity"));
|
|
239
237
|
}
|
|
240
238
|
if (!app.queueChannel) {
|
|
@@ -303,11 +301,15 @@ var startWorkloop = (app, logger, minBackoff, maxBackoff, maxWorkers) => {
|
|
|
303
301
|
}
|
|
304
302
|
};
|
|
305
303
|
workLoop();
|
|
306
|
-
return
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
304
|
+
return {
|
|
305
|
+
stop: (reason = "reason unknown") => {
|
|
306
|
+
if (!cancelled) {
|
|
307
|
+
logger.info(`cancelling workloop: ${reason}`);
|
|
308
|
+
cancelled = true;
|
|
309
|
+
promise.cancel();
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
isStopped: () => cancelled
|
|
311
313
|
};
|
|
312
314
|
};
|
|
313
315
|
var workloop_default = startWorkloop;
|
|
@@ -1018,16 +1020,7 @@ function connect(app, logger, options = {}) {
|
|
|
1018
1020
|
logger.success("Connected to Lightning at", options.lightning);
|
|
1019
1021
|
app.socket = socket;
|
|
1020
1022
|
app.queueChannel = channel;
|
|
1021
|
-
if (
|
|
1022
|
-
logger.info("Starting workloop");
|
|
1023
|
-
app.killWorkloop = workloop_default(
|
|
1024
|
-
app,
|
|
1025
|
-
logger,
|
|
1026
|
-
options.backoff?.min || MIN_BACKOFF,
|
|
1027
|
-
options.backoff?.max || MAX_BACKOFF,
|
|
1028
|
-
options.maxWorkflows
|
|
1029
|
-
);
|
|
1030
|
-
} else {
|
|
1023
|
+
if (options.noLoop) {
|
|
1031
1024
|
const port = app.server?.address().port;
|
|
1032
1025
|
logger.break();
|
|
1033
1026
|
logger.warn("Noloop active: workloop has not started");
|
|
@@ -1036,17 +1029,17 @@ function connect(app, logger, options = {}) {
|
|
|
1036
1029
|
logger.info(` curl -X POST http://localhost:${port}/claim`);
|
|
1037
1030
|
logger.break();
|
|
1038
1031
|
}
|
|
1032
|
+
app.resumeWorkloop();
|
|
1039
1033
|
};
|
|
1040
1034
|
const onDisconnect = () => {
|
|
1041
|
-
if (app.
|
|
1042
|
-
app.
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
}
|
|
1035
|
+
if (!app.workloop?.isStopped()) {
|
|
1036
|
+
app.workloop?.stop("Socket disconnected unexpectedly");
|
|
1037
|
+
}
|
|
1038
|
+
if (!app.destroyed) {
|
|
1039
|
+
logger.info("Connection to lightning lost");
|
|
1040
|
+
logger.info(
|
|
1041
|
+
"Worker will automatically reconnect when lightning is back online"
|
|
1042
|
+
);
|
|
1050
1043
|
}
|
|
1051
1044
|
};
|
|
1052
1045
|
const onError = (e) => {
|
|
@@ -1089,6 +1082,21 @@ function createServer(engine, options = {}) {
|
|
|
1089
1082
|
router.get("/livez", healthcheck_default);
|
|
1090
1083
|
router.get("/", healthcheck_default);
|
|
1091
1084
|
app.options = options;
|
|
1085
|
+
app.resumeWorkloop = () => {
|
|
1086
|
+
if (options.noLoop) {
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
if (!app.workloop || app.workloop?.isStopped()) {
|
|
1090
|
+
logger.info("Starting workloop");
|
|
1091
|
+
app.workloop = workloop_default(
|
|
1092
|
+
app,
|
|
1093
|
+
logger,
|
|
1094
|
+
options.backoff?.min || MIN_BACKOFF,
|
|
1095
|
+
options.backoff?.max || MAX_BACKOFF,
|
|
1096
|
+
options.maxWorkflows
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
};
|
|
1092
1100
|
app.execute = async ({ id, token }) => {
|
|
1093
1101
|
if (app.socket) {
|
|
1094
1102
|
try {
|
|
@@ -1111,6 +1119,7 @@ function createServer(engine, options = {}) {
|
|
|
1111
1119
|
delete app.workflows[id];
|
|
1112
1120
|
runChannel.leave();
|
|
1113
1121
|
app.events.emit(INTERNAL_RUN_COMPLETE);
|
|
1122
|
+
app.resumeWorkloop();
|
|
1114
1123
|
};
|
|
1115
1124
|
const context = execute(
|
|
1116
1125
|
runChannel,
|
package/dist/start.js
CHANGED
|
@@ -37,7 +37,7 @@ var name, version, description, main, type, scripts, bin, author, license, depen
|
|
|
37
37
|
var init_package = __esm({
|
|
38
38
|
"package.json"() {
|
|
39
39
|
name = "@openfn/ws-worker";
|
|
40
|
-
version = "1.
|
|
40
|
+
version = "1.7.0";
|
|
41
41
|
description = "A Websocket Worker to connect Lightning to a Runtime Engine";
|
|
42
42
|
main = "dist/index.js";
|
|
43
43
|
type = "module";
|
|
@@ -271,7 +271,7 @@ var destroy = async (app, logger2) => {
|
|
|
271
271
|
await Promise.all([
|
|
272
272
|
new Promise((resolve5) => {
|
|
273
273
|
app.destroyed = true;
|
|
274
|
-
app.
|
|
274
|
+
app.workloop?.stop("server closed");
|
|
275
275
|
app.queueChannel?.leave();
|
|
276
276
|
app.server.close(async () => {
|
|
277
277
|
resolve5();
|
|
@@ -371,9 +371,7 @@ var claim = (app, logger2 = mockLogger, options = {}) => {
|
|
|
371
371
|
const { maxWorkers = 5 } = options;
|
|
372
372
|
const activeWorkers = Object.keys(app.workflows).length;
|
|
373
373
|
if (activeWorkers >= maxWorkers) {
|
|
374
|
-
|
|
375
|
-
`skipping claim attempt: server at capacity (${activeWorkers}/${maxWorkers})`
|
|
376
|
-
);
|
|
374
|
+
app.workloop?.stop(`server at capacity (${activeWorkers}/${maxWorkers})`);
|
|
377
375
|
return reject(new Error("Server at capacity"));
|
|
378
376
|
}
|
|
379
377
|
if (!app.queueChannel) {
|
|
@@ -442,11 +440,15 @@ var startWorkloop = (app, logger2, minBackoff2, maxBackoff2, maxWorkers) => {
|
|
|
442
440
|
}
|
|
443
441
|
};
|
|
444
442
|
workLoop();
|
|
445
|
-
return
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
443
|
+
return {
|
|
444
|
+
stop: (reason = "reason unknown") => {
|
|
445
|
+
if (!cancelled) {
|
|
446
|
+
logger2.info(`cancelling workloop: ${reason}`);
|
|
447
|
+
cancelled = true;
|
|
448
|
+
promise.cancel();
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
isStopped: () => cancelled
|
|
450
452
|
};
|
|
451
453
|
};
|
|
452
454
|
var workloop_default = startWorkloop;
|
|
@@ -1157,16 +1159,7 @@ function connect(app, logger2, options = {}) {
|
|
|
1157
1159
|
logger2.success("Connected to Lightning at", options.lightning);
|
|
1158
1160
|
app.socket = socket;
|
|
1159
1161
|
app.queueChannel = channel;
|
|
1160
|
-
if (
|
|
1161
|
-
logger2.info("Starting workloop");
|
|
1162
|
-
app.killWorkloop = workloop_default(
|
|
1163
|
-
app,
|
|
1164
|
-
logger2,
|
|
1165
|
-
options.backoff?.min || MIN_BACKOFF,
|
|
1166
|
-
options.backoff?.max || MAX_BACKOFF,
|
|
1167
|
-
options.maxWorkflows
|
|
1168
|
-
);
|
|
1169
|
-
} else {
|
|
1162
|
+
if (options.noLoop) {
|
|
1170
1163
|
const port = app.server?.address().port;
|
|
1171
1164
|
logger2.break();
|
|
1172
1165
|
logger2.warn("Noloop active: workloop has not started");
|
|
@@ -1175,17 +1168,17 @@ function connect(app, logger2, options = {}) {
|
|
|
1175
1168
|
logger2.info(` curl -X POST http://localhost:${port}/claim`);
|
|
1176
1169
|
logger2.break();
|
|
1177
1170
|
}
|
|
1171
|
+
app.resumeWorkloop();
|
|
1178
1172
|
};
|
|
1179
1173
|
const onDisconnect = () => {
|
|
1180
|
-
if (app.
|
|
1181
|
-
app.
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
}
|
|
1174
|
+
if (!app.workloop?.isStopped()) {
|
|
1175
|
+
app.workloop?.stop("Socket disconnected unexpectedly");
|
|
1176
|
+
}
|
|
1177
|
+
if (!app.destroyed) {
|
|
1178
|
+
logger2.info("Connection to lightning lost");
|
|
1179
|
+
logger2.info(
|
|
1180
|
+
"Worker will automatically reconnect when lightning is back online"
|
|
1181
|
+
);
|
|
1189
1182
|
}
|
|
1190
1183
|
};
|
|
1191
1184
|
const onError = (e) => {
|
|
@@ -1228,6 +1221,21 @@ function createServer(engine, options = {}) {
|
|
|
1228
1221
|
router.get("/livez", healthcheck_default);
|
|
1229
1222
|
router.get("/", healthcheck_default);
|
|
1230
1223
|
app.options = options;
|
|
1224
|
+
app.resumeWorkloop = () => {
|
|
1225
|
+
if (options.noLoop) {
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
if (!app.workloop || app.workloop?.isStopped()) {
|
|
1229
|
+
logger2.info("Starting workloop");
|
|
1230
|
+
app.workloop = workloop_default(
|
|
1231
|
+
app,
|
|
1232
|
+
logger2,
|
|
1233
|
+
options.backoff?.min || MIN_BACKOFF,
|
|
1234
|
+
options.backoff?.max || MAX_BACKOFF,
|
|
1235
|
+
options.maxWorkflows
|
|
1236
|
+
);
|
|
1237
|
+
}
|
|
1238
|
+
};
|
|
1231
1239
|
app.execute = async ({ id, token }) => {
|
|
1232
1240
|
if (app.socket) {
|
|
1233
1241
|
try {
|
|
@@ -1250,6 +1258,7 @@ function createServer(engine, options = {}) {
|
|
|
1250
1258
|
delete app.workflows[id];
|
|
1251
1259
|
runChannel.leave();
|
|
1252
1260
|
app.events.emit(INTERNAL_RUN_COMPLETE);
|
|
1261
|
+
app.resumeWorkloop();
|
|
1253
1262
|
};
|
|
1254
1263
|
const context = execute(
|
|
1255
1264
|
runChannel,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/ws-worker",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.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,8 +22,8 @@
|
|
|
22
22
|
"koa-logger": "^3.2.1",
|
|
23
23
|
"phoenix": "1.7.10",
|
|
24
24
|
"ws": "^8.18.0",
|
|
25
|
-
"@openfn/engine-multi": "1.2.5",
|
|
26
25
|
"@openfn/lexicon": "^1.1.0",
|
|
26
|
+
"@openfn/engine-multi": "1.3.0",
|
|
27
27
|
"@openfn/runtime": "1.4.2",
|
|
28
28
|
"@openfn/logger": "1.0.2"
|
|
29
29
|
},
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"tsup": "^6.2.3",
|
|
43
43
|
"typescript": "^4.6.4",
|
|
44
44
|
"yargs": "^17.6.2",
|
|
45
|
-
"@openfn/lightning-mock": "2.0.
|
|
45
|
+
"@openfn/lightning-mock": "2.0.20"
|
|
46
46
|
},
|
|
47
47
|
"files": [
|
|
48
48
|
"dist",
|