@openfn/ws-worker 1.14.3 → 1.14.5
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 +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +22 -6
- package/dist/start.js +22 -6
- package/package.json +25 -25
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# ws-worker
|
|
2
2
|
|
|
3
|
+
## 1.14.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Update dependencies
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @openfn/engine-multi@1.6.9
|
|
10
|
+
- @openfn/lexicon@1.2.3
|
|
11
|
+
- @openfn/runtime@1.7.2
|
|
12
|
+
- @openfn/logger@1.0.6
|
|
13
|
+
|
|
14
|
+
## 1.14.4
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 5a613e7: Adjust logging
|
|
19
|
+
- 3a33557: Count outstanding claim requests as capacity. This fixes an issue where `work-available` messages can cause a worker to over-claim, particularly during periods of high load on the Lightning database.
|
|
20
|
+
|
|
3
21
|
## 1.14.3
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -140,14 +140,25 @@ var ClaimError = class extends Error {
|
|
|
140
140
|
this.abort = true;
|
|
141
141
|
}
|
|
142
142
|
};
|
|
143
|
+
var claimIdGen = 0;
|
|
143
144
|
var claim = (app, logger = mockLogger, options = {}) => {
|
|
144
145
|
return new Promise((resolve, reject) => {
|
|
145
|
-
|
|
146
|
+
app.openClaims ??= {};
|
|
147
|
+
const { maxWorkers = 5, demand = 1 } = options;
|
|
146
148
|
const podName = NAME ? `[${NAME}] ` : "";
|
|
147
149
|
const activeWorkers = Object.keys(app.workflows).length;
|
|
150
|
+
const pendingClaims = Object.values(app.openClaims).reduce(
|
|
151
|
+
(a, b) => a + b,
|
|
152
|
+
0
|
|
153
|
+
);
|
|
148
154
|
if (activeWorkers >= maxWorkers) {
|
|
149
155
|
app.workloop?.stop(`server at capacity (${activeWorkers}/${maxWorkers})`);
|
|
150
156
|
return reject(new ClaimError("Server at capacity"));
|
|
157
|
+
} else if (activeWorkers + pendingClaims >= maxWorkers) {
|
|
158
|
+
app.workloop?.stop(
|
|
159
|
+
`server at capacity (${activeWorkers}/${maxWorkers}, ${pendingClaims} pending)`
|
|
160
|
+
);
|
|
161
|
+
return reject(new ClaimError("Server at capacity"));
|
|
151
162
|
}
|
|
152
163
|
if (!app.queueChannel) {
|
|
153
164
|
logger.warn("skipping claim attempt: websocket unavailable");
|
|
@@ -159,12 +170,15 @@ var claim = (app, logger = mockLogger, options = {}) => {
|
|
|
159
170
|
logger.warn("skipping claim attempt: channel closed");
|
|
160
171
|
return reject(e);
|
|
161
172
|
}
|
|
173
|
+
const claimId = ++claimIdGen;
|
|
174
|
+
app.openClaims[claimId] = demand;
|
|
162
175
|
logger.debug(`requesting run (capacity ${activeWorkers}/${maxWorkers})`);
|
|
163
176
|
const start = Date.now();
|
|
164
177
|
app.queueChannel.push(CLAIM, {
|
|
165
|
-
demand
|
|
178
|
+
demand,
|
|
166
179
|
worker_name: NAME || null
|
|
167
180
|
}).receive("ok", ({ runs }) => {
|
|
181
|
+
delete app.openClaims[claimId];
|
|
168
182
|
const duration = Date.now() - start;
|
|
169
183
|
logger.debug(
|
|
170
184
|
`${podName}claimed ${runs.length} runs in ${duration}ms (${runs.length ? runs.map((r) => r.id).join(",") : "-"})`
|
|
@@ -192,8 +206,11 @@ var claim = (app, logger = mockLogger, options = {}) => {
|
|
|
192
206
|
resolve();
|
|
193
207
|
});
|
|
194
208
|
}).receive("error", (e) => {
|
|
209
|
+
delete app.openClaims[claimId];
|
|
195
210
|
logger.error("Error on claim", e);
|
|
211
|
+
reject(new Error("claim error"));
|
|
196
212
|
}).receive("timeout", () => {
|
|
213
|
+
delete app.openClaims[claimId];
|
|
197
214
|
logger.error("TIMEOUT on claim. Runs may be lost.");
|
|
198
215
|
reject(new Error("timeout"));
|
|
199
216
|
});
|
|
@@ -1015,9 +1032,8 @@ var joinRunChannel = (socket, token, runId, logger, timeout = 30) => {
|
|
|
1015
1032
|
channel.onClose(() => {
|
|
1016
1033
|
logger.debug(`Leaving ${channelName}`);
|
|
1017
1034
|
});
|
|
1018
|
-
channel.onError((
|
|
1019
|
-
logger.debug(`
|
|
1020
|
-
logger.debug(e);
|
|
1035
|
+
channel.onError((...args) => {
|
|
1036
|
+
logger.debug(`Critical error in channel ${channelName}`, args);
|
|
1021
1037
|
});
|
|
1022
1038
|
});
|
|
1023
1039
|
};
|
|
@@ -1240,6 +1256,7 @@ function createServer(engine, options = {}) {
|
|
|
1240
1256
|
logger.debug(str);
|
|
1241
1257
|
})
|
|
1242
1258
|
);
|
|
1259
|
+
app.openClaims = {};
|
|
1243
1260
|
app.workflows = {};
|
|
1244
1261
|
app.destroyed = false;
|
|
1245
1262
|
app.server = app.listen(port);
|
|
@@ -1279,7 +1296,6 @@ function createServer(engine, options = {}) {
|
|
|
1279
1296
|
collectionsVersion: app.options.collectionsVersion,
|
|
1280
1297
|
monorepoPath: app.options.monorepoDir
|
|
1281
1298
|
});
|
|
1282
|
-
logger.debug("converted run body into execution plan:", plan);
|
|
1283
1299
|
if (plan.workflow.credentials?.collections_token) {
|
|
1284
1300
|
plan.workflow.credentials.collections_token = token;
|
|
1285
1301
|
}
|
package/dist/start.js
CHANGED
|
@@ -280,14 +280,25 @@ var ClaimError = class extends Error {
|
|
|
280
280
|
this.abort = true;
|
|
281
281
|
}
|
|
282
282
|
};
|
|
283
|
+
var claimIdGen = 0;
|
|
283
284
|
var claim = (app, logger2 = mockLogger, options = {}) => {
|
|
284
285
|
return new Promise((resolve5, reject) => {
|
|
285
|
-
|
|
286
|
+
app.openClaims ??= {};
|
|
287
|
+
const { maxWorkers = 5, demand = 1 } = options;
|
|
286
288
|
const podName = NAME ? `[${NAME}] ` : "";
|
|
287
289
|
const activeWorkers = Object.keys(app.workflows).length;
|
|
290
|
+
const pendingClaims = Object.values(app.openClaims).reduce(
|
|
291
|
+
(a, b) => a + b,
|
|
292
|
+
0
|
|
293
|
+
);
|
|
288
294
|
if (activeWorkers >= maxWorkers) {
|
|
289
295
|
app.workloop?.stop(`server at capacity (${activeWorkers}/${maxWorkers})`);
|
|
290
296
|
return reject(new ClaimError("Server at capacity"));
|
|
297
|
+
} else if (activeWorkers + pendingClaims >= maxWorkers) {
|
|
298
|
+
app.workloop?.stop(
|
|
299
|
+
`server at capacity (${activeWorkers}/${maxWorkers}, ${pendingClaims} pending)`
|
|
300
|
+
);
|
|
301
|
+
return reject(new ClaimError("Server at capacity"));
|
|
291
302
|
}
|
|
292
303
|
if (!app.queueChannel) {
|
|
293
304
|
logger2.warn("skipping claim attempt: websocket unavailable");
|
|
@@ -299,12 +310,15 @@ var claim = (app, logger2 = mockLogger, options = {}) => {
|
|
|
299
310
|
logger2.warn("skipping claim attempt: channel closed");
|
|
300
311
|
return reject(e);
|
|
301
312
|
}
|
|
313
|
+
const claimId = ++claimIdGen;
|
|
314
|
+
app.openClaims[claimId] = demand;
|
|
302
315
|
logger2.debug(`requesting run (capacity ${activeWorkers}/${maxWorkers})`);
|
|
303
316
|
const start = Date.now();
|
|
304
317
|
app.queueChannel.push(CLAIM, {
|
|
305
|
-
demand
|
|
318
|
+
demand,
|
|
306
319
|
worker_name: NAME || null
|
|
307
320
|
}).receive("ok", ({ runs }) => {
|
|
321
|
+
delete app.openClaims[claimId];
|
|
308
322
|
const duration = Date.now() - start;
|
|
309
323
|
logger2.debug(
|
|
310
324
|
`${podName}claimed ${runs.length} runs in ${duration}ms (${runs.length ? runs.map((r) => r.id).join(",") : "-"})`
|
|
@@ -332,8 +346,11 @@ var claim = (app, logger2 = mockLogger, options = {}) => {
|
|
|
332
346
|
resolve5();
|
|
333
347
|
});
|
|
334
348
|
}).receive("error", (e) => {
|
|
349
|
+
delete app.openClaims[claimId];
|
|
335
350
|
logger2.error("Error on claim", e);
|
|
351
|
+
reject(new Error("claim error"));
|
|
336
352
|
}).receive("timeout", () => {
|
|
353
|
+
delete app.openClaims[claimId];
|
|
337
354
|
logger2.error("TIMEOUT on claim. Runs may be lost.");
|
|
338
355
|
reject(new Error("timeout"));
|
|
339
356
|
});
|
|
@@ -1155,9 +1172,8 @@ var joinRunChannel = (socket, token, runId, logger2, timeout = 30) => {
|
|
|
1155
1172
|
channel.onClose(() => {
|
|
1156
1173
|
logger2.debug(`Leaving ${channelName}`);
|
|
1157
1174
|
});
|
|
1158
|
-
channel.onError((
|
|
1159
|
-
logger2.debug(`
|
|
1160
|
-
logger2.debug(e);
|
|
1175
|
+
channel.onError((...args2) => {
|
|
1176
|
+
logger2.debug(`Critical error in channel ${channelName}`, args2);
|
|
1161
1177
|
});
|
|
1162
1178
|
});
|
|
1163
1179
|
};
|
|
@@ -1380,6 +1396,7 @@ function createServer(engine, options = {}) {
|
|
|
1380
1396
|
logger2.debug(str);
|
|
1381
1397
|
})
|
|
1382
1398
|
);
|
|
1399
|
+
app.openClaims = {};
|
|
1383
1400
|
app.workflows = {};
|
|
1384
1401
|
app.destroyed = false;
|
|
1385
1402
|
app.server = app.listen(port);
|
|
@@ -1419,7 +1436,6 @@ function createServer(engine, options = {}) {
|
|
|
1419
1436
|
collectionsVersion: app.options.collectionsVersion,
|
|
1420
1437
|
monorepoPath: app.options.monorepoDir
|
|
1421
1438
|
});
|
|
1422
|
-
logger2.debug("converted run body into execution plan:", plan);
|
|
1423
1439
|
if (plan.workflow.credentials?.collections_token) {
|
|
1424
1440
|
plan.workflow.credentials.collections_token = token;
|
|
1425
1441
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/ws-worker",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.5",
|
|
4
4
|
"description": "A Websocket Worker to connect Lightning to a Runtime Engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -10,40 +10,40 @@
|
|
|
10
10
|
"author": "Open Function Group <admin@openfn.org>",
|
|
11
11
|
"license": "ISC",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@koa/router": "^12.0.
|
|
14
|
-
"@sentry/node": "^9.
|
|
15
|
-
"@types/koa-logger": "^3.1.
|
|
16
|
-
"@types/ws": "^8.
|
|
13
|
+
"@koa/router": "^12.0.2",
|
|
14
|
+
"@sentry/node": "^9.46.0",
|
|
15
|
+
"@types/koa-logger": "^3.1.5",
|
|
16
|
+
"@types/ws": "^8.18.1",
|
|
17
17
|
"fast-safe-stringify": "^2.1.1",
|
|
18
18
|
"figures": "^5.0.0",
|
|
19
|
-
"human-id": "^4.1.
|
|
19
|
+
"human-id": "^4.1.1",
|
|
20
20
|
"jose": "^4.15.9",
|
|
21
|
-
"koa": "^2.
|
|
22
|
-
"koa-bodyparser": "^4.4.
|
|
21
|
+
"koa": "^2.16.2",
|
|
22
|
+
"koa-bodyparser": "^4.4.1",
|
|
23
23
|
"koa-logger": "^3.2.1",
|
|
24
24
|
"phoenix": "1.7.10",
|
|
25
|
-
"ws": "^8.18.
|
|
26
|
-
"@openfn/engine-multi": "1.6.
|
|
27
|
-
"@openfn/
|
|
28
|
-
"@openfn/runtime": "1.7.
|
|
29
|
-
"@openfn/
|
|
25
|
+
"ws": "^8.18.3",
|
|
26
|
+
"@openfn/engine-multi": "1.6.9",
|
|
27
|
+
"@openfn/lexicon": "^1.2.3",
|
|
28
|
+
"@openfn/runtime": "1.7.2",
|
|
29
|
+
"@openfn/logger": "1.0.6"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@types/koa": "^2.
|
|
33
|
-
"@types/koa-bodyparser": "^4.3.
|
|
34
|
-
"@types/koa__router": "^12.0.
|
|
35
|
-
"@types/node": "^18.
|
|
32
|
+
"@types/koa": "^2.15.0",
|
|
33
|
+
"@types/koa-bodyparser": "^4.3.12",
|
|
34
|
+
"@types/koa__router": "^12.0.4",
|
|
35
|
+
"@types/node": "^18.19.127",
|
|
36
36
|
"@types/nodemon": "1.19.3",
|
|
37
|
-
"@types/phoenix": "^1.6.
|
|
38
|
-
"@types/yargs": "^17.0.
|
|
37
|
+
"@types/phoenix": "^1.6.6",
|
|
38
|
+
"@types/yargs": "^17.0.33",
|
|
39
39
|
"ava": "5.1.0",
|
|
40
40
|
"nodemon": "3.0.1",
|
|
41
|
-
"sentry-testkit": "^6.
|
|
42
|
-
"tslib": "^2.
|
|
43
|
-
"tsup": "^6.
|
|
44
|
-
"typescript": "^4.
|
|
45
|
-
"yargs": "^17.
|
|
46
|
-
"@openfn/lightning-mock": "2.2.
|
|
41
|
+
"sentry-testkit": "^6.2.2",
|
|
42
|
+
"tslib": "^2.8.1",
|
|
43
|
+
"tsup": "^6.7.0",
|
|
44
|
+
"typescript": "^4.9.5",
|
|
45
|
+
"yargs": "^17.7.2",
|
|
46
|
+
"@openfn/lightning-mock": "2.2.4"
|
|
47
47
|
},
|
|
48
48
|
"files": [
|
|
49
49
|
"dist",
|