@openfn/ws-worker 1.13.0 → 1.13.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 +7 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -7
- package/dist/start.js +32 -13
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -124,9 +124,11 @@ var verifyToken = async (token, publicKey) => {
|
|
|
124
124
|
return true;
|
|
125
125
|
}
|
|
126
126
|
};
|
|
127
|
+
var { DEPLOYED_POD_NAME } = process.env;
|
|
127
128
|
var claim = (app, logger = mockLogger, options = {}) => {
|
|
128
129
|
return new Promise((resolve, reject) => {
|
|
129
130
|
const { maxWorkers = 5 } = options;
|
|
131
|
+
const podName = DEPLOYED_POD_NAME ? `[${DEPLOYED_POD_NAME}] ` : "";
|
|
130
132
|
const activeWorkers = Object.keys(app.workflows).length;
|
|
131
133
|
if (activeWorkers >= maxWorkers) {
|
|
132
134
|
app.workloop?.stop(`server at capacity (${activeWorkers}/${maxWorkers})`);
|
|
@@ -138,10 +140,10 @@ var claim = (app, logger = mockLogger, options = {}) => {
|
|
|
138
140
|
}
|
|
139
141
|
logger.debug(`requesting run (capacity ${activeWorkers}/${maxWorkers})`);
|
|
140
142
|
const start = Date.now();
|
|
141
|
-
app.queueChannel.push(CLAIM, { demand: 1 }).receive("ok", ({ runs }) => {
|
|
143
|
+
app.queueChannel.push(CLAIM, { demand: 1, pod_name: DEPLOYED_POD_NAME }).receive("ok", ({ runs }) => {
|
|
142
144
|
const duration = Date.now() - start;
|
|
143
145
|
logger.debug(
|
|
144
|
-
|
|
146
|
+
`${podName}claimed ${runs.length} runs in ${duration}ms (${runs.length ? runs.map((r) => r.id).join(",") : "-"})`
|
|
145
147
|
);
|
|
146
148
|
if (!runs?.length) {
|
|
147
149
|
return reject(new Error("No runs returned"));
|
|
@@ -161,7 +163,7 @@ var claim = (app, logger = mockLogger, options = {}) => {
|
|
|
161
163
|
} else {
|
|
162
164
|
logger.debug("skipping run token validation for", run.id);
|
|
163
165
|
}
|
|
164
|
-
logger.debug(
|
|
166
|
+
logger.debug(`${podName} starting run ${run.id}`);
|
|
165
167
|
app.execute(run);
|
|
166
168
|
resolve();
|
|
167
169
|
});
|
|
@@ -939,13 +941,14 @@ var healthcheck_default = (ctx) => {
|
|
|
939
941
|
|
|
940
942
|
// src/channels/run.ts
|
|
941
943
|
import * as Sentry3 from "@sentry/node";
|
|
942
|
-
var joinRunChannel = (socket, token, runId, logger) => {
|
|
944
|
+
var joinRunChannel = (socket, token, runId, logger, timeout = 30) => {
|
|
943
945
|
return new Promise((resolve, reject) => {
|
|
944
946
|
let didReceiveOk = false;
|
|
945
947
|
const channelName = `run:${runId}`;
|
|
946
|
-
logger.
|
|
948
|
+
logger.info(`JOINING ${channelName}`);
|
|
949
|
+
logger.debug(`connecting to ${channelName} with timeout ${timeout}s`);
|
|
947
950
|
const channel = socket.channel(channelName, { token });
|
|
948
|
-
channel.join().receive("ok", async (e) => {
|
|
951
|
+
channel.join(timeout * 1e3).receive("ok", async (e) => {
|
|
949
952
|
if (!didReceiveOk) {
|
|
950
953
|
didReceiveOk = true;
|
|
951
954
|
logger.success(`connected to ${channelName}`, e);
|
|
@@ -958,10 +961,12 @@ var joinRunChannel = (socket, token, runId, logger) => {
|
|
|
958
961
|
}).receive("error", (err) => {
|
|
959
962
|
Sentry3.captureException(err);
|
|
960
963
|
logger.error(`error connecting to ${channelName}`, err);
|
|
964
|
+
channel?.leave();
|
|
961
965
|
reject(err);
|
|
962
966
|
}).receive("timeout", (err) => {
|
|
963
967
|
Sentry3.captureException(err);
|
|
964
968
|
logger.error(`Timeout for ${channelName}`, err);
|
|
969
|
+
channel?.leave();
|
|
965
970
|
reject(err);
|
|
966
971
|
});
|
|
967
972
|
channel.onClose(() => {
|
|
@@ -1216,7 +1221,8 @@ function createServer(engine, options = {}) {
|
|
|
1216
1221
|
app.socket,
|
|
1217
1222
|
token,
|
|
1218
1223
|
id,
|
|
1219
|
-
logger
|
|
1224
|
+
logger,
|
|
1225
|
+
app.options.messageTimeoutSeconds
|
|
1220
1226
|
);
|
|
1221
1227
|
const { plan, options: options2, input } = convert_lightning_plan_default(run, {
|
|
1222
1228
|
collectionsVersion: app.options.collectionsVersion,
|
|
@@ -1253,6 +1259,8 @@ function createServer(engine, options = {}) {
|
|
|
1253
1259
|
);
|
|
1254
1260
|
app.workflows[id] = context;
|
|
1255
1261
|
} catch (e) {
|
|
1262
|
+
delete app.workflows[id];
|
|
1263
|
+
app.resumeWorkloop();
|
|
1256
1264
|
logger.error(`Unexpected error executing ${id}`);
|
|
1257
1265
|
logger.error(e);
|
|
1258
1266
|
}
|
package/dist/start.js
CHANGED
|
@@ -264,9 +264,11 @@ var verifyToken = async (token, publicKey) => {
|
|
|
264
264
|
return true;
|
|
265
265
|
}
|
|
266
266
|
};
|
|
267
|
+
var { DEPLOYED_POD_NAME } = process.env;
|
|
267
268
|
var claim = (app, logger2 = mockLogger, options = {}) => {
|
|
268
269
|
return new Promise((resolve5, reject) => {
|
|
269
270
|
const { maxWorkers = 5 } = options;
|
|
271
|
+
const podName = DEPLOYED_POD_NAME ? `[${DEPLOYED_POD_NAME}] ` : "";
|
|
270
272
|
const activeWorkers = Object.keys(app.workflows).length;
|
|
271
273
|
if (activeWorkers >= maxWorkers) {
|
|
272
274
|
app.workloop?.stop(`server at capacity (${activeWorkers}/${maxWorkers})`);
|
|
@@ -278,10 +280,10 @@ var claim = (app, logger2 = mockLogger, options = {}) => {
|
|
|
278
280
|
}
|
|
279
281
|
logger2.debug(`requesting run (capacity ${activeWorkers}/${maxWorkers})`);
|
|
280
282
|
const start = Date.now();
|
|
281
|
-
app.queueChannel.push(CLAIM, { demand: 1 }).receive("ok", ({ runs }) => {
|
|
283
|
+
app.queueChannel.push(CLAIM, { demand: 1, pod_name: DEPLOYED_POD_NAME }).receive("ok", ({ runs }) => {
|
|
282
284
|
const duration = Date.now() - start;
|
|
283
285
|
logger2.debug(
|
|
284
|
-
|
|
286
|
+
`${podName}claimed ${runs.length} runs in ${duration}ms (${runs.length ? runs.map((r) => r.id).join(",") : "-"})`
|
|
285
287
|
);
|
|
286
288
|
if (!runs?.length) {
|
|
287
289
|
return reject(new Error("No runs returned"));
|
|
@@ -301,7 +303,7 @@ var claim = (app, logger2 = mockLogger, options = {}) => {
|
|
|
301
303
|
} else {
|
|
302
304
|
logger2.debug("skipping run token validation for", run2.id);
|
|
303
305
|
}
|
|
304
|
-
logger2.debug(
|
|
306
|
+
logger2.debug(`${podName} starting run ${run2.id}`);
|
|
305
307
|
app.execute(run2);
|
|
306
308
|
resolve5();
|
|
307
309
|
});
|
|
@@ -1079,13 +1081,14 @@ var healthcheck_default = (ctx) => {
|
|
|
1079
1081
|
|
|
1080
1082
|
// src/channels/run.ts
|
|
1081
1083
|
import * as Sentry3 from "@sentry/node";
|
|
1082
|
-
var joinRunChannel = (socket, token, runId, logger2) => {
|
|
1084
|
+
var joinRunChannel = (socket, token, runId, logger2, timeout = 30) => {
|
|
1083
1085
|
return new Promise((resolve5, reject) => {
|
|
1084
1086
|
let didReceiveOk = false;
|
|
1085
1087
|
const channelName = `run:${runId}`;
|
|
1086
|
-
logger2.
|
|
1088
|
+
logger2.info(`JOINING ${channelName}`);
|
|
1089
|
+
logger2.debug(`connecting to ${channelName} with timeout ${timeout}s`);
|
|
1087
1090
|
const channel = socket.channel(channelName, { token });
|
|
1088
|
-
channel.join().receive("ok", async (e) => {
|
|
1091
|
+
channel.join(timeout * 1e3).receive("ok", async (e) => {
|
|
1089
1092
|
if (!didReceiveOk) {
|
|
1090
1093
|
didReceiveOk = true;
|
|
1091
1094
|
logger2.success(`connected to ${channelName}`, e);
|
|
@@ -1098,10 +1101,12 @@ var joinRunChannel = (socket, token, runId, logger2) => {
|
|
|
1098
1101
|
}).receive("error", (err) => {
|
|
1099
1102
|
Sentry3.captureException(err);
|
|
1100
1103
|
logger2.error(`error connecting to ${channelName}`, err);
|
|
1104
|
+
channel?.leave();
|
|
1101
1105
|
reject(err);
|
|
1102
1106
|
}).receive("timeout", (err) => {
|
|
1103
1107
|
Sentry3.captureException(err);
|
|
1104
1108
|
logger2.error(`Timeout for ${channelName}`, err);
|
|
1109
|
+
channel?.leave();
|
|
1105
1110
|
reject(err);
|
|
1106
1111
|
});
|
|
1107
1112
|
channel.onClose(() => {
|
|
@@ -1356,7 +1361,8 @@ function createServer(engine, options = {}) {
|
|
|
1356
1361
|
app.socket,
|
|
1357
1362
|
token,
|
|
1358
1363
|
id,
|
|
1359
|
-
logger2
|
|
1364
|
+
logger2,
|
|
1365
|
+
app.options.messageTimeoutSeconds
|
|
1360
1366
|
);
|
|
1361
1367
|
const { plan, options: options2, input } = convert_lightning_plan_default(run2, {
|
|
1362
1368
|
collectionsVersion: app.options.collectionsVersion,
|
|
@@ -1393,6 +1399,8 @@ function createServer(engine, options = {}) {
|
|
|
1393
1399
|
);
|
|
1394
1400
|
app.workflows[id] = context;
|
|
1395
1401
|
} catch (e) {
|
|
1402
|
+
delete app.workflows[id];
|
|
1403
|
+
app.resumeWorkloop();
|
|
1396
1404
|
logger2.error(`Unexpected error executing ${id}`);
|
|
1397
1405
|
logger2.error(e);
|
|
1398
1406
|
}
|
|
@@ -6302,6 +6310,7 @@ var yargs_default = Yargs;
|
|
|
6302
6310
|
var DEFAULT_PORT2 = 2222;
|
|
6303
6311
|
var DEFAULT_WORKER_CAPACITY = 5;
|
|
6304
6312
|
var DEFAULT_SOCKET_TIMEOUT_SECONDS = 10;
|
|
6313
|
+
var DEFAULT_MESSAGE_TIMEOUT_SECONDS = 30;
|
|
6305
6314
|
function setArg(argValue, envValue, defaultValue) {
|
|
6306
6315
|
if (Array.isArray(defaultValue) && !argValue && typeof envValue === "string") {
|
|
6307
6316
|
return envValue.split(",");
|
|
@@ -6313,24 +6322,25 @@ function setArg(argValue, envValue, defaultValue) {
|
|
|
6313
6322
|
}
|
|
6314
6323
|
function parseArgs(argv) {
|
|
6315
6324
|
const {
|
|
6325
|
+
OPENFN_ADAPTORS_REPO,
|
|
6316
6326
|
WORKER_BACKOFF,
|
|
6317
6327
|
WORKER_CAPACITY,
|
|
6318
|
-
WORKER_COLLECTIONS_VERSION,
|
|
6319
6328
|
WORKER_COLLECTIONS_URL,
|
|
6329
|
+
WORKER_COLLECTIONS_VERSION,
|
|
6320
6330
|
WORKER_LIGHTNING_PUBLIC_KEY,
|
|
6321
6331
|
WORKER_LIGHTNING_SERVICE_URL,
|
|
6322
6332
|
WORKER_LOG_LEVEL,
|
|
6323
6333
|
WORKER_MAX_PAYLOAD_MB,
|
|
6324
6334
|
WORKER_MAX_RUN_DURATION_SECONDS,
|
|
6325
6335
|
WORKER_MAX_RUN_MEMORY_MB,
|
|
6336
|
+
WORKER_MESSAGE_TIMEOUT_SECONDS,
|
|
6326
6337
|
WORKER_PORT,
|
|
6327
6338
|
WORKER_REPO_DIR,
|
|
6328
6339
|
WORKER_SECRET,
|
|
6329
6340
|
WORKER_SENTRY_DSN,
|
|
6330
6341
|
WORKER_SENTRY_ENV,
|
|
6331
|
-
WORKER_STATE_PROPS_TO_REMOVE,
|
|
6332
6342
|
WORKER_SOCKET_TIMEOUT_SECONDS,
|
|
6333
|
-
|
|
6343
|
+
WORKER_STATE_PROPS_TO_REMOVE
|
|
6334
6344
|
} = process.env;
|
|
6335
6345
|
const parser2 = yargs_default(hideBin(argv)).command("server", "Start a ws-worker server").option("port", {
|
|
6336
6346
|
alias: "p",
|
|
@@ -6344,7 +6354,7 @@ function parseArgs(argv) {
|
|
|
6344
6354
|
description: "Path to the runtime repo (where modules will be installed). Env: WORKER_REPO_DIR"
|
|
6345
6355
|
}).option("monorepo-dir", {
|
|
6346
6356
|
alias: "m",
|
|
6347
|
-
description: "Path to the adaptors
|
|
6357
|
+
description: "Path to the adaptors monorepo, from where @local adaptors will be loaded. Env: OPENFN_ADAPTORS_REPO"
|
|
6348
6358
|
}).option("secret", {
|
|
6349
6359
|
alias: "s",
|
|
6350
6360
|
description: "Worker secret. (comes from WORKER_SECRET by default). Env: WORKER_SECRET"
|
|
@@ -6354,7 +6364,9 @@ function parseArgs(argv) {
|
|
|
6354
6364
|
}).option("sentry-env", {
|
|
6355
6365
|
description: "Sentry environment. Defaults to 'dev'. Env: WORKER_SENTRY_ENV"
|
|
6356
6366
|
}).option("socket-timeout", {
|
|
6357
|
-
description: `Timeout for websockets to
|
|
6367
|
+
description: `Timeout for websockets to Lightning, in seconds. Defaults to 10.Env: WORKER_SOCKET_TIMEOUT_SECONDS`
|
|
6368
|
+
}).option("message-timeout", {
|
|
6369
|
+
description: `Timeout for messages in the run channel in seconds. Defaults to 1. Env: WORKER_MESSAGE_TIMEOUT_SECONDS`
|
|
6358
6370
|
}).option("lightning-public-key", {
|
|
6359
6371
|
description: "Base64-encoded public key. Used to verify run tokens. Env: WORKER_LIGHTNING_PUBLIC_KEY"
|
|
6360
6372
|
}).option("log", {
|
|
@@ -6430,6 +6442,11 @@ function parseArgs(argv) {
|
|
|
6430
6442
|
WORKER_SOCKET_TIMEOUT_SECONDS,
|
|
6431
6443
|
DEFAULT_SOCKET_TIMEOUT_SECONDS
|
|
6432
6444
|
),
|
|
6445
|
+
messageTimeoutSeconds: setArg(
|
|
6446
|
+
args2.messageTimeoutSeconds,
|
|
6447
|
+
WORKER_MESSAGE_TIMEOUT_SECONDS,
|
|
6448
|
+
DEFAULT_MESSAGE_TIMEOUT_SECONDS
|
|
6449
|
+
),
|
|
6433
6450
|
collectionsVersion: setArg(
|
|
6434
6451
|
args2.collectionsVersion,
|
|
6435
6452
|
WORKER_COLLECTIONS_VERSION
|
|
@@ -6471,7 +6488,9 @@ function engineReady(engine) {
|
|
|
6471
6488
|
payloadLimitMb: args.payloadMemory,
|
|
6472
6489
|
collectionsVersion: args.collectionsVersion,
|
|
6473
6490
|
collectionsUrl: args.collectionsUrl,
|
|
6474
|
-
monorepoDir: args.monorepoDir
|
|
6491
|
+
monorepoDir: args.monorepoDir,
|
|
6492
|
+
messageTimeoutSeconds: args.messageTimeoutSeconds,
|
|
6493
|
+
socketTimeoutSeconds: args.socketTimeoutSeconds
|
|
6475
6494
|
};
|
|
6476
6495
|
if (args.lightningPublicKey) {
|
|
6477
6496
|
logger.info(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/ws-worker",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.1",
|
|
4
4
|
"description": "A Websocket Worker to connect Lightning to a Runtime Engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"koa-logger": "^3.2.1",
|
|
24
24
|
"phoenix": "1.7.10",
|
|
25
25
|
"ws": "^8.18.0",
|
|
26
|
-
"@openfn/
|
|
26
|
+
"@openfn/lexicon": "^1.2.0",
|
|
27
27
|
"@openfn/logger": "1.0.5",
|
|
28
28
|
"@openfn/runtime": "1.6.4",
|
|
29
|
-
"@openfn/
|
|
29
|
+
"@openfn/engine-multi": "1.6.2"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/koa": "^2.13.5",
|