@aikirun/worker 0.18.0 → 0.20.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/dist/index.js +45 -28
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1327,18 +1327,32 @@ var WorkerHandleImpl = class {
|
|
|
1327
1327
|
logger;
|
|
1328
1328
|
abortController;
|
|
1329
1329
|
subscriberStrategy;
|
|
1330
|
+
fallbackSubscriberStrategy;
|
|
1330
1331
|
pollPromise;
|
|
1331
1332
|
activeWorkflowRunsById = /* @__PURE__ */ new Map();
|
|
1332
1333
|
async _start() {
|
|
1334
|
+
const workflows = this.registry.getAll();
|
|
1335
|
+
const subscriberStrategyParams = this.params.subscriber ?? { type: "db" };
|
|
1333
1336
|
const subscriberStrategyBuilder = this.client[INTERNAL7].subscriber.create(
|
|
1334
|
-
|
|
1335
|
-
|
|
1337
|
+
subscriberStrategyParams,
|
|
1338
|
+
workflows,
|
|
1336
1339
|
this.spawnOpts.shards
|
|
1337
1340
|
);
|
|
1338
1341
|
this.subscriberStrategy = await subscriberStrategyBuilder.init(this.id, {
|
|
1339
1342
|
onError: (error) => this.handleSubscriberError(error),
|
|
1340
1343
|
onStop: () => this.stop()
|
|
1341
1344
|
});
|
|
1345
|
+
if (subscriberStrategyParams.type !== "db") {
|
|
1346
|
+
const fallbackSubscriberStrategyBuilder = this.client[INTERNAL7].subscriber.create(
|
|
1347
|
+
{ type: "db" },
|
|
1348
|
+
workflows,
|
|
1349
|
+
this.spawnOpts.shards
|
|
1350
|
+
);
|
|
1351
|
+
this.fallbackSubscriberStrategy = await fallbackSubscriberStrategyBuilder.init(this.id, {
|
|
1352
|
+
onError: (error) => this.handleSubscriberError(error),
|
|
1353
|
+
onStop: () => this.stop()
|
|
1354
|
+
});
|
|
1355
|
+
}
|
|
1342
1356
|
this.abortController = new AbortController();
|
|
1343
1357
|
const abortSignal = this.abortController.signal;
|
|
1344
1358
|
this.pollPromise = this.poll(abortSignal).catch((error) => {
|
|
@@ -1387,7 +1401,7 @@ var WorkerHandleImpl = class {
|
|
|
1387
1401
|
nextDelayMs = this.subscriberStrategy.getNextDelay({ type: "at_capacity" });
|
|
1388
1402
|
continue;
|
|
1389
1403
|
}
|
|
1390
|
-
const nextBatchResponse = await this.fetchNextWorkflowRunBatch(availableCapacity);
|
|
1404
|
+
const nextBatchResponse = await this.fetchNextWorkflowRunBatch(availableCapacity, subscriberFailedAttempts);
|
|
1391
1405
|
if (!nextBatchResponse.success) {
|
|
1392
1406
|
subscriberFailedAttempts++;
|
|
1393
1407
|
nextDelayMs = this.subscriberStrategy.getNextDelay({
|
|
@@ -1401,11 +1415,11 @@ var WorkerHandleImpl = class {
|
|
|
1401
1415
|
nextDelayMs = this.subscriberStrategy.getNextDelay({ type: "polled", foundWork: false });
|
|
1402
1416
|
continue;
|
|
1403
1417
|
}
|
|
1404
|
-
await this.enqueueWorkflowRunBatch(nextBatchResponse.batch, abortSignal);
|
|
1418
|
+
await this.enqueueWorkflowRunBatch(nextBatchResponse.batch, nextBatchResponse.subscriber, abortSignal);
|
|
1405
1419
|
nextDelayMs = this.subscriberStrategy.getNextDelay({ type: "polled", foundWork: true });
|
|
1406
1420
|
}
|
|
1407
1421
|
}
|
|
1408
|
-
async fetchNextWorkflowRunBatch(size) {
|
|
1422
|
+
async fetchNextWorkflowRunBatch(size, subscriberFailedAttempts) {
|
|
1409
1423
|
if (!this.subscriberStrategy) {
|
|
1410
1424
|
return {
|
|
1411
1425
|
success: false,
|
|
@@ -1414,22 +1428,26 @@ var WorkerHandleImpl = class {
|
|
|
1414
1428
|
}
|
|
1415
1429
|
try {
|
|
1416
1430
|
const batch = await this.subscriberStrategy.getNextBatch(size);
|
|
1417
|
-
return {
|
|
1418
|
-
success: true,
|
|
1419
|
-
batch
|
|
1420
|
-
};
|
|
1431
|
+
return { success: true, batch, subscriber: this.subscriberStrategy };
|
|
1421
1432
|
} catch (error) {
|
|
1422
1433
|
this.logger.error("Error getting next workflow runs batch", {
|
|
1423
1434
|
"aiki.error": error instanceof Error ? error.message : String(error)
|
|
1424
1435
|
});
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1436
|
+
if (this.fallbackSubscriberStrategy && subscriberFailedAttempts >= 2) {
|
|
1437
|
+
try {
|
|
1438
|
+
const batch = await this.fallbackSubscriberStrategy.getNextBatch(size);
|
|
1439
|
+
return { success: true, batch, subscriber: this.fallbackSubscriberStrategy };
|
|
1440
|
+
} catch (fallbackError) {
|
|
1441
|
+
this.logger.error("Fallback subscriber strategy for getting next workflow runs batch also failed", {
|
|
1442
|
+
"aiki.error": fallbackError instanceof Error ? fallbackError.message : String(fallbackError)
|
|
1443
|
+
});
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
return { success: false, error };
|
|
1429
1447
|
}
|
|
1430
1448
|
}
|
|
1431
|
-
async enqueueWorkflowRunBatch(batch, abortSignal) {
|
|
1432
|
-
for (const { data
|
|
1449
|
+
async enqueueWorkflowRunBatch(batch, subscriber, abortSignal) {
|
|
1450
|
+
for (const { data } of batch) {
|
|
1433
1451
|
const { workflowRunId } = data;
|
|
1434
1452
|
if (this.activeWorkflowRunsById.has(workflowRunId)) {
|
|
1435
1453
|
this.logger.info("Workflow already running", {
|
|
@@ -1439,8 +1457,8 @@ var WorkerHandleImpl = class {
|
|
|
1439
1457
|
}
|
|
1440
1458
|
const { run: workflowRun } = await this.client.api.workflowRun.getByIdV1({ id: workflowRunId });
|
|
1441
1459
|
if (!workflowRun) {
|
|
1442
|
-
if (
|
|
1443
|
-
await
|
|
1460
|
+
if (subscriber.acknowledge) {
|
|
1461
|
+
await subscriber.acknowledge(workflowRunId).catch(() => {
|
|
1444
1462
|
});
|
|
1445
1463
|
}
|
|
1446
1464
|
continue;
|
|
@@ -1455,8 +1473,8 @@ var WorkerHandleImpl = class {
|
|
|
1455
1473
|
"aiki.workflowVersionId": workflowRun.versionId,
|
|
1456
1474
|
"aiki.workflowRunId": workflowRun.id
|
|
1457
1475
|
});
|
|
1458
|
-
if (
|
|
1459
|
-
await
|
|
1476
|
+
if (subscriber.acknowledge) {
|
|
1477
|
+
await subscriber.acknowledge(workflowRunId).catch(() => {
|
|
1460
1478
|
});
|
|
1461
1479
|
}
|
|
1462
1480
|
continue;
|
|
@@ -1464,15 +1482,14 @@ var WorkerHandleImpl = class {
|
|
|
1464
1482
|
if (abortSignal.aborted) {
|
|
1465
1483
|
break;
|
|
1466
1484
|
}
|
|
1467
|
-
const workflowExecutionPromise = this.executeWorkflow(workflowRun, workflowVersion,
|
|
1485
|
+
const workflowExecutionPromise = this.executeWorkflow(workflowRun, workflowVersion, subscriber);
|
|
1468
1486
|
this.activeWorkflowRunsById.set(workflowRun.id, {
|
|
1469
1487
|
run: workflowRun,
|
|
1470
|
-
executionPromise: workflowExecutionPromise
|
|
1471
|
-
meta
|
|
1488
|
+
executionPromise: workflowExecutionPromise
|
|
1472
1489
|
});
|
|
1473
1490
|
}
|
|
1474
1491
|
}
|
|
1475
|
-
async executeWorkflow(workflowRun, workflowVersion,
|
|
1492
|
+
async executeWorkflow(workflowRun, workflowVersion, subscriber) {
|
|
1476
1493
|
const logger = this.logger.child({
|
|
1477
1494
|
"aiki.component": "workflow-execution",
|
|
1478
1495
|
"aiki.workflowName": workflowRun.name,
|
|
@@ -1482,11 +1499,11 @@ var WorkerHandleImpl = class {
|
|
|
1482
1499
|
let heartbeatInterval;
|
|
1483
1500
|
let shouldAcknowledge = false;
|
|
1484
1501
|
try {
|
|
1485
|
-
const heartbeat =
|
|
1486
|
-
if (
|
|
1502
|
+
const heartbeat = subscriber.heartbeat;
|
|
1503
|
+
if (heartbeat) {
|
|
1487
1504
|
heartbeatInterval = setInterval(() => {
|
|
1488
1505
|
try {
|
|
1489
|
-
heartbeat(workflowRun.id
|
|
1506
|
+
heartbeat(workflowRun.id);
|
|
1490
1507
|
} catch (error) {
|
|
1491
1508
|
logger.warn("Failed to send heartbeat", {
|
|
1492
1509
|
"aiki.error": error instanceof Error ? error.message : String(error)
|
|
@@ -1528,10 +1545,10 @@ var WorkerHandleImpl = class {
|
|
|
1528
1545
|
}
|
|
1529
1546
|
} finally {
|
|
1530
1547
|
if (heartbeatInterval) clearInterval(heartbeatInterval);
|
|
1531
|
-
if (
|
|
1548
|
+
if (subscriber.acknowledge) {
|
|
1532
1549
|
if (shouldAcknowledge) {
|
|
1533
1550
|
try {
|
|
1534
|
-
await
|
|
1551
|
+
await subscriber.acknowledge(workflowRun.id);
|
|
1535
1552
|
} catch (error) {
|
|
1536
1553
|
logger.error("Failed to acknowledge message, it may be reprocessed", {
|
|
1537
1554
|
"aiki.errorType": "MESSAGE_ACK_FAILED",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aikirun/worker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Worker SDK for Aiki - execute workflows and tasks with durable state management and automatic recovery",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"build": "tsup"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@aikirun/types": "0.
|
|
22
|
-
"@aikirun/client": "0.
|
|
23
|
-
"@aikirun/workflow": "0.
|
|
21
|
+
"@aikirun/types": "0.20.0",
|
|
22
|
+
"@aikirun/client": "0.20.0",
|
|
23
|
+
"@aikirun/workflow": "0.20.0",
|
|
24
24
|
"ulidx": "^2.4.1"
|
|
25
25
|
},
|
|
26
26
|
"publishConfig": {
|