@orion-js/dogs 4.6.7 → 4.6.9
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/LICENSE +21 -0
- package/dist/index.cjs +186 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +186 -25
- package/dist/index.js.map +1 -1
- package/dist/repos/JobsRepo.d.ts +1 -0
- package/dist/services/Executor.d.ts +6 -0
- package/dist/services/WorkerService.d.ts +3 -0
- package/dist/services/jobFilters.d.ts +21 -0
- package/dist/types/JobsDefinition.d.ts +7 -0
- package/dist/types/StartConfig.d.ts +39 -0
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Orionjs Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
CHANGED
|
@@ -524,6 +524,17 @@ var JobsRepo = class {
|
|
|
524
524
|
);
|
|
525
525
|
return result.matchedCount > 0;
|
|
526
526
|
}
|
|
527
|
+
async rescheduleAfterExecutionGuardAcquisitionFailure(jobId, lockId, nextRunAt) {
|
|
528
|
+
const result = await this.jobs.updateOne(
|
|
529
|
+
{ _id: jobId, lockId, tries: { $gte: 1 } },
|
|
530
|
+
{
|
|
531
|
+
$set: { nextRunAt },
|
|
532
|
+
$inc: { tries: -1 },
|
|
533
|
+
$unset: { lockId: "", lockedUntil: "", claimWasStale: "" }
|
|
534
|
+
}
|
|
535
|
+
);
|
|
536
|
+
return result.matchedCount > 0;
|
|
537
|
+
}
|
|
527
538
|
async deleteEventJob(jobId, lockId) {
|
|
528
539
|
const result = await this.jobs.deleteOne({
|
|
529
540
|
_id: jobId,
|
|
@@ -872,7 +883,7 @@ function scheduleJobsInternal(jobs, nPartitions) {
|
|
|
872
883
|
|
|
873
884
|
// src/services/WorkerService.ts
|
|
874
885
|
var import_helpers2 = require("@orion-js/helpers");
|
|
875
|
-
var
|
|
886
|
+
var import_logger5 = require("@orion-js/logger");
|
|
876
887
|
var import_services4 = require("@orion-js/services");
|
|
877
888
|
|
|
878
889
|
// src/services/Executor.ts
|
|
@@ -1124,6 +1135,42 @@ var Executor = class {
|
|
|
1124
1135
|
}
|
|
1125
1136
|
return false;
|
|
1126
1137
|
}
|
|
1138
|
+
async handleExecutionGuardAcquisitionFailure(error, config, jobToRun, context) {
|
|
1139
|
+
context.logger.error(`Error acquiring execution guard for job "${jobToRun.name}"`, { error });
|
|
1140
|
+
const nextRunAt = new Date(Date.now() + (config.executionGuardRetryDelayMs ?? 1e3));
|
|
1141
|
+
try {
|
|
1142
|
+
const didReschedule = await this.jobsRepo.rescheduleAfterExecutionGuardAcquisitionFailure(
|
|
1143
|
+
jobToRun.jobId,
|
|
1144
|
+
jobToRun.lockId,
|
|
1145
|
+
nextRunAt
|
|
1146
|
+
);
|
|
1147
|
+
if (!didReschedule) {
|
|
1148
|
+
context.logger.warn(
|
|
1149
|
+
`Could not requeue job "${jobToRun.name}" after execution guard acquisition failed because its lock is no longer owned`
|
|
1150
|
+
);
|
|
1151
|
+
}
|
|
1152
|
+
} catch (rescheduleError) {
|
|
1153
|
+
context.logger.error(
|
|
1154
|
+
`Error requeueing job "${jobToRun.name}" after execution guard acquisition failed`,
|
|
1155
|
+
{ error: rescheduleError }
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
async releaseExecutionGuardLease(lease, jobToRun, context) {
|
|
1160
|
+
try {
|
|
1161
|
+
await lease.release();
|
|
1162
|
+
} catch (error) {
|
|
1163
|
+
context.logger.error(`Error releasing execution guard for job "${jobToRun.name}"`, { error });
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
async runGuardedResolver(job, jobToRun, context, lease) {
|
|
1167
|
+
try {
|
|
1168
|
+
return await job.resolve(jobToRun.params, context);
|
|
1169
|
+
} finally {
|
|
1170
|
+
context.clearStaleTimeout();
|
|
1171
|
+
await this.releaseExecutionGuardLease(lease, jobToRun, context);
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1127
1174
|
async executeJob(config, jobToRun, onExecutionStale) {
|
|
1128
1175
|
const job = this.getJobDefinition(jobToRun, config.jobs);
|
|
1129
1176
|
if (!job) return;
|
|
@@ -1205,13 +1252,36 @@ var Executor = class {
|
|
|
1205
1252
|
params: jobToRun.params
|
|
1206
1253
|
};
|
|
1207
1254
|
await (0, import_logger3.runWithOrionAsyncContext)(extraContext, async () => {
|
|
1208
|
-
|
|
1255
|
+
let executionGuardLease;
|
|
1256
|
+
if (config.executionGuard) {
|
|
1209
1257
|
(0, import_logger3.updateOrionAsyncContext)({
|
|
1210
1258
|
jobName: jobToRun.name,
|
|
1211
1259
|
jobId: jobToRun.jobId,
|
|
1212
1260
|
params: jobToRun.params
|
|
1213
1261
|
});
|
|
1214
|
-
|
|
1262
|
+
try {
|
|
1263
|
+
executionGuardLease = await config.executionGuard.acquire(jobToRun);
|
|
1264
|
+
} catch (error) {
|
|
1265
|
+
context.clearStaleTimeout();
|
|
1266
|
+
await this.handleExecutionGuardAcquisitionFailure(error, config, jobToRun, context);
|
|
1267
|
+
if (executionStatus === "stale") await staleHandlingPromise;
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
if (executionStatus === "stale") {
|
|
1271
|
+
await staleHandlingPromise;
|
|
1272
|
+
await this.releaseExecutionGuardLease(executionGuardLease, jobToRun, context);
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
try {
|
|
1277
|
+
if (!config.executionGuard) {
|
|
1278
|
+
(0, import_logger3.updateOrionAsyncContext)({
|
|
1279
|
+
jobName: jobToRun.name,
|
|
1280
|
+
jobId: jobToRun.jobId,
|
|
1281
|
+
params: jobToRun.params
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
const result = executionGuardLease ? await this.runGuardedResolver(job, jobToRun, context, executionGuardLease) : await job.resolve(jobToRun.params, context);
|
|
1215
1285
|
context.clearStaleTimeout();
|
|
1216
1286
|
if (executionStatus === "stale") {
|
|
1217
1287
|
await staleHandlingPromise;
|
|
@@ -1280,6 +1350,76 @@ __decorateElement(_init4, 5, "jobsHistoryRepo", _jobsHistoryRepo_dec, Executor);
|
|
|
1280
1350
|
Executor = __decorateElement(_init4, 0, "Executor", _Executor_decorators, Executor);
|
|
1281
1351
|
__runInitializers(_init4, 1, Executor);
|
|
1282
1352
|
|
|
1353
|
+
// src/services/jobFilters.ts
|
|
1354
|
+
var import_logger4 = require("@orion-js/logger");
|
|
1355
|
+
var DEFAULT_JOBS_FILTER_TIMEOUT_MS = 5e3;
|
|
1356
|
+
var warnedUnknownJobNames = /* @__PURE__ */ new Set();
|
|
1357
|
+
async function withTimeout(promise, timeoutMs, name) {
|
|
1358
|
+
let timer;
|
|
1359
|
+
const timeout = new Promise((_, reject) => {
|
|
1360
|
+
timer = setTimeout(() => reject(new Error(`${name} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
1361
|
+
});
|
|
1362
|
+
try {
|
|
1363
|
+
return await Promise.race([promise, timeout]);
|
|
1364
|
+
} finally {
|
|
1365
|
+
clearTimeout(timer);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
async function runCheck(options, name, run) {
|
|
1369
|
+
if (options.pendingChecks.has(name)) {
|
|
1370
|
+
throw new Error(`${name} is still running from a previous claim`);
|
|
1371
|
+
}
|
|
1372
|
+
const promise = Promise.resolve().then(run);
|
|
1373
|
+
options.pendingChecks.set(name, promise);
|
|
1374
|
+
void promise.then(
|
|
1375
|
+
() => options.pendingChecks.delete(name),
|
|
1376
|
+
() => options.pendingChecks.delete(name)
|
|
1377
|
+
);
|
|
1378
|
+
return await withTimeout(promise, options.timeoutMs, name);
|
|
1379
|
+
}
|
|
1380
|
+
function warnUnknownJobNames(jobs, filter) {
|
|
1381
|
+
for (const jobName of [...filter.allow ?? [], ...filter.deny ?? []]) {
|
|
1382
|
+
if (jobs[jobName] || warnedUnknownJobNames.has(jobName)) continue;
|
|
1383
|
+
warnedUnknownJobNames.add(jobName);
|
|
1384
|
+
import_logger4.logger.warn(`getJobsFilter returned unknown job name "${jobName}"; it will be ignored.`);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
async function filterByJobsFilter(options, getJobsFilter) {
|
|
1388
|
+
try {
|
|
1389
|
+
const filter = await runCheck(options, "getJobsFilter", getJobsFilter) ?? {};
|
|
1390
|
+
warnUnknownJobNames(options.jobs, filter);
|
|
1391
|
+
return options.jobNames.filter((jobName) => {
|
|
1392
|
+
var _a;
|
|
1393
|
+
if (filter.allow && !filter.allow.includes(jobName)) return false;
|
|
1394
|
+
if ((_a = filter.deny) == null ? void 0 : _a.includes(jobName)) return false;
|
|
1395
|
+
return true;
|
|
1396
|
+
});
|
|
1397
|
+
} catch (error) {
|
|
1398
|
+
import_logger4.logger.error("Error in getJobsFilter; no jobs will be taken on this claim.", { error });
|
|
1399
|
+
return [];
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
async function canTakeJob(options, jobName) {
|
|
1403
|
+
const canTakeJobs = options.jobs[jobName].canTakeJobs;
|
|
1404
|
+
if (!canTakeJobs) return true;
|
|
1405
|
+
try {
|
|
1406
|
+
return await runCheck(options, `canTakeJobs of "${jobName}"`, canTakeJobs) === true;
|
|
1407
|
+
} catch (error) {
|
|
1408
|
+
import_logger4.logger.error(`Error in canTakeJobs of job "${jobName}"; it will not be taken.`, { error });
|
|
1409
|
+
return false;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
async function getTakeableJobNames(inputOptions) {
|
|
1413
|
+
const options = {
|
|
1414
|
+
timeoutMs: DEFAULT_JOBS_FILTER_TIMEOUT_MS,
|
|
1415
|
+
pendingChecks: /* @__PURE__ */ new Map(),
|
|
1416
|
+
...inputOptions
|
|
1417
|
+
};
|
|
1418
|
+
const jobNames = inputOptions.getJobsFilter ? await filterByJobsFilter(options, inputOptions.getJobsFilter) : options.jobNames;
|
|
1419
|
+
const checks = await Promise.all(jobNames.map((jobName) => canTakeJob(options, jobName)));
|
|
1420
|
+
return jobNames.filter((_, index) => checks[index]);
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1283
1423
|
// src/services/WorkerService.ts
|
|
1284
1424
|
var FILTERED_JOB_NAMES_ACQUISITION_HINT = "byJobName";
|
|
1285
1425
|
var _executor_dec, _jobsRepo_dec3, _WorkerService_decorators, _init5;
|
|
@@ -1291,6 +1431,7 @@ var WorkerService = class {
|
|
|
1291
1431
|
__publicField(this, "partitionReconcilerJitterMs", 30 * 1e3);
|
|
1292
1432
|
__publicField(this, "partitionReconcilerBatchPauseMs", 250);
|
|
1293
1433
|
__publicField(this, "partitionReconcilerBatchSize", 500);
|
|
1434
|
+
__publicField(this, "jobsFilterTimeoutMs", DEFAULT_JOBS_FILTER_TIMEOUT_MS);
|
|
1294
1435
|
__publicField(this, "jobsRepo", __runInitializers(_init5, 8, this)), __runInitializers(_init5, 11, this);
|
|
1295
1436
|
__publicField(this, "executor", __runInitializers(_init5, 12, this)), __runInitializers(_init5, 15, this);
|
|
1296
1437
|
}
|
|
@@ -1349,13 +1490,13 @@ var WorkerService = class {
|
|
|
1349
1490
|
};
|
|
1350
1491
|
this.reserveJobExecution(workersInstance, jobToRun.name);
|
|
1351
1492
|
workersInstance.activeExecutions.set(jobToRun.executionId, execution);
|
|
1352
|
-
|
|
1493
|
+
import_logger5.logger.debug(`Starting job execution "${jobToRun.executionId}"`, jobToRun);
|
|
1353
1494
|
const executionPromise = this.executor.executeJob(config, jobToRun, () => {
|
|
1354
1495
|
this.releaseExecutionCapacity(workersInstance, execution, "stale");
|
|
1355
1496
|
});
|
|
1356
1497
|
execution.promise = executionPromise;
|
|
1357
1498
|
void executionPromise.catch((error) => {
|
|
1358
|
-
|
|
1499
|
+
import_logger5.logger.error(`Unhandled error executing job "${jobToRun.name}"`, { error });
|
|
1359
1500
|
}).finally(() => {
|
|
1360
1501
|
if (execution.status === "running") {
|
|
1361
1502
|
this.releaseExecutionCapacity(workersInstance, execution, "finished");
|
|
@@ -1390,20 +1531,39 @@ var WorkerService = class {
|
|
|
1390
1531
|
jobs: config.jobs,
|
|
1391
1532
|
maxTries: config.maxTries,
|
|
1392
1533
|
maxTriesReachedRetentionMs: config.maxTriesReachedRetentionMs,
|
|
1393
|
-
onMaxTriesReached: config.onMaxTriesReached
|
|
1534
|
+
onMaxTriesReached: config.onMaxTriesReached,
|
|
1535
|
+
...config.executionGuard ? {
|
|
1536
|
+
executionGuard: config.executionGuard,
|
|
1537
|
+
executionGuardRetryDelayMs: Math.max(config.pollInterval, 1e3)
|
|
1538
|
+
} : {}
|
|
1394
1539
|
};
|
|
1395
|
-
|
|
1540
|
+
import_logger5.logger.debug(`Running scheduler loop for jobs "${jobNames.join(", ")}"...`);
|
|
1396
1541
|
let consecutivePartitionMisses = 0;
|
|
1397
1542
|
while (workersInstance.running) {
|
|
1398
1543
|
let didMiss = false;
|
|
1399
1544
|
let allJobNamesAtCapacity = false;
|
|
1400
1545
|
try {
|
|
1401
1546
|
while (workersInstance.activeExecutions.size < config.workersCount) {
|
|
1402
|
-
const
|
|
1403
|
-
if (
|
|
1547
|
+
const jobNamesWithCapacity = this.getAvailableJobNames(config, workersInstance, jobNames);
|
|
1548
|
+
if (jobNamesWithCapacity.length === 0) {
|
|
1404
1549
|
allJobNamesAtCapacity = workersInstance.activeExecutions.size > 0;
|
|
1405
1550
|
break;
|
|
1406
1551
|
}
|
|
1552
|
+
const availableJobNames = await Promise.race([
|
|
1553
|
+
getTakeableJobNames({
|
|
1554
|
+
jobs: config.jobs,
|
|
1555
|
+
getJobsFilter: config.getJobsFilter,
|
|
1556
|
+
jobNames: jobNamesWithCapacity,
|
|
1557
|
+
timeoutMs: this.jobsFilterTimeoutMs,
|
|
1558
|
+
pendingChecks: workersInstance.pendingFilterChecks
|
|
1559
|
+
}),
|
|
1560
|
+
workersInstance.stopSignal.then(() => [])
|
|
1561
|
+
]);
|
|
1562
|
+
if (!workersInstance.running) break;
|
|
1563
|
+
if (availableJobNames.length === 0) {
|
|
1564
|
+
didMiss = true;
|
|
1565
|
+
break;
|
|
1566
|
+
}
|
|
1407
1567
|
const jobAcquisitionHint = availableJobNames.length < jobNames.length ? FILTERED_JOB_NAMES_ACQUISITION_HINT : workersInstance.jobAcquisitionHint;
|
|
1408
1568
|
const partition = this.getNextPartition(config, workersInstance);
|
|
1409
1569
|
const jobToRun = await this.jobsRepo.getJobAndLock(
|
|
@@ -1414,7 +1574,7 @@ var WorkerService = class {
|
|
|
1414
1574
|
);
|
|
1415
1575
|
if (!jobToRun) {
|
|
1416
1576
|
consecutivePartitionMisses++;
|
|
1417
|
-
|
|
1577
|
+
import_logger5.logger.debug(`No job to run in partition ${partition}`);
|
|
1418
1578
|
if (consecutivePartitionMisses >= config.nPartitions) {
|
|
1419
1579
|
consecutivePartitionMisses = 0;
|
|
1420
1580
|
didMiss = true;
|
|
@@ -1427,7 +1587,7 @@ var WorkerService = class {
|
|
|
1427
1587
|
if (!workersInstance.running) break;
|
|
1428
1588
|
}
|
|
1429
1589
|
} catch (error) {
|
|
1430
|
-
|
|
1590
|
+
import_logger5.logger.error("Error in job scheduler.", { error });
|
|
1431
1591
|
consecutivePartitionMisses = 0;
|
|
1432
1592
|
didMiss = true;
|
|
1433
1593
|
}
|
|
@@ -1479,7 +1639,7 @@ var WorkerService = class {
|
|
|
1479
1639
|
} catch (error) {
|
|
1480
1640
|
this.resetPendingJobAcquisitionHint(workersInstance);
|
|
1481
1641
|
if (workersInstance.running) {
|
|
1482
|
-
|
|
1642
|
+
import_logger5.logger.warn("Job acquisition hint probe failed; keeping the current hint.", { error });
|
|
1483
1643
|
}
|
|
1484
1644
|
return;
|
|
1485
1645
|
}
|
|
@@ -1492,12 +1652,12 @@ var WorkerService = class {
|
|
|
1492
1652
|
workersInstance.hasCompletedInitialJobAcquisitionHintProbe = true;
|
|
1493
1653
|
workersInstance.jobAcquisitionHint = winner;
|
|
1494
1654
|
this.resetPendingJobAcquisitionHint(workersInstance);
|
|
1495
|
-
|
|
1655
|
+
import_logger5.logger.info(`Selected job acquisition hint "${winner}" after startup probe.`);
|
|
1496
1656
|
return;
|
|
1497
1657
|
}
|
|
1498
1658
|
if (winner === currentHint) {
|
|
1499
1659
|
this.resetPendingJobAcquisitionHint(workersInstance);
|
|
1500
|
-
|
|
1660
|
+
import_logger5.logger.debug(`Keeping job acquisition hint "${currentHint}" after probe.`);
|
|
1501
1661
|
return;
|
|
1502
1662
|
}
|
|
1503
1663
|
if (workersInstance.pendingJobAcquisitionHint === winner) {
|
|
@@ -1507,14 +1667,14 @@ var WorkerService = class {
|
|
|
1507
1667
|
workersInstance.pendingJobAcquisitionHintWins = 1;
|
|
1508
1668
|
}
|
|
1509
1669
|
if (workersInstance.pendingJobAcquisitionHintWins < 2) {
|
|
1510
|
-
|
|
1670
|
+
import_logger5.logger.debug(
|
|
1511
1671
|
`Keeping job acquisition hint "${currentHint}"; "${winner}" has one consecutive probe win.`
|
|
1512
1672
|
);
|
|
1513
1673
|
return;
|
|
1514
1674
|
}
|
|
1515
1675
|
workersInstance.jobAcquisitionHint = winner;
|
|
1516
1676
|
this.resetPendingJobAcquisitionHint(workersInstance);
|
|
1517
|
-
|
|
1677
|
+
import_logger5.logger.info(`Changed job acquisition hint from "${currentHint}" to "${winner}".`);
|
|
1518
1678
|
}
|
|
1519
1679
|
async waitForNextJobAcquisitionHintProbe(workersInstance) {
|
|
1520
1680
|
await new Promise((resolve) => {
|
|
@@ -1551,7 +1711,7 @@ var WorkerService = class {
|
|
|
1551
1711
|
batchSize: this.partitionReconcilerBatchSize
|
|
1552
1712
|
});
|
|
1553
1713
|
} catch (error) {
|
|
1554
|
-
|
|
1714
|
+
import_logger5.logger.warn("Job partition reconciliation failed; it will be retried.", { error });
|
|
1555
1715
|
return 0;
|
|
1556
1716
|
}
|
|
1557
1717
|
}
|
|
@@ -1591,6 +1751,7 @@ var WorkerService = class {
|
|
|
1591
1751
|
activeExecutions: /* @__PURE__ */ new Map(),
|
|
1592
1752
|
staleExecutions: /* @__PURE__ */ new Map(),
|
|
1593
1753
|
runningJobsByName: /* @__PURE__ */ new Map(),
|
|
1754
|
+
pendingFilterChecks: /* @__PURE__ */ new Map(),
|
|
1594
1755
|
jobAcquisitionHint: INITIAL_JOB_ACQUISITION_HINT,
|
|
1595
1756
|
jobAcquisitionHintProbeCycle: 0,
|
|
1596
1757
|
hasCompletedInitialJobAcquisitionHintProbe: false,
|
|
@@ -1609,7 +1770,7 @@ var WorkerService = class {
|
|
|
1609
1770
|
if (workersInstance.stopPromise) return workersInstance.stopPromise;
|
|
1610
1771
|
workersInstance.stopPromise = (async () => {
|
|
1611
1772
|
var _a, _b;
|
|
1612
|
-
|
|
1773
|
+
import_logger5.logger.info("Stopping job scheduler...");
|
|
1613
1774
|
workersInstance.running = false;
|
|
1614
1775
|
workersInstance.signalStop();
|
|
1615
1776
|
(_a = workersInstance.cancelJobAcquisitionHintProbeWait) == null ? void 0 : _a.call(workersInstance);
|
|
@@ -1634,17 +1795,17 @@ var WorkerService = class {
|
|
|
1634
1795
|
const jobs = this.getJobs(config.jobs);
|
|
1635
1796
|
await Promise.all(
|
|
1636
1797
|
jobs.filter((job) => job.type === "recurrent").map(async (job) => {
|
|
1637
|
-
|
|
1798
|
+
import_logger5.logger.debug(`Ensuring records for job "${job.name}"...`);
|
|
1638
1799
|
await this.jobsRepo.ensureJobRecord(job, getRandomPartition(config.nPartitions));
|
|
1639
1800
|
})
|
|
1640
1801
|
);
|
|
1641
1802
|
}
|
|
1642
1803
|
async runScheduler(config, workersInstance) {
|
|
1643
|
-
|
|
1644
|
-
void this.jobsRepo.ensureMaxTriesReachedRetention(config.maxTriesReachedRetentionMs).catch((error) =>
|
|
1645
|
-
|
|
1804
|
+
import_logger5.logger.debug("Will ensure maxTriesReached retention and TTL index");
|
|
1805
|
+
void this.jobsRepo.ensureMaxTriesReachedRetention(config.maxTriesReachedRetentionMs).catch((error) => import_logger5.logger.error("Error ensuring maxTriesReached retention", { error }));
|
|
1806
|
+
import_logger5.logger.debug("Will ensure records for recurrent jobs");
|
|
1646
1807
|
await this.ensureRecords(config);
|
|
1647
|
-
|
|
1808
|
+
import_logger5.logger.info(`Starting job scheduler with concurrency ${config.workersCount}`);
|
|
1648
1809
|
await this.runSchedulerLoop(config, workersInstance);
|
|
1649
1810
|
}
|
|
1650
1811
|
/**
|
|
@@ -1670,7 +1831,7 @@ var WorkerService = class {
|
|
|
1670
1831
|
setNameToJobs(config.jobs, config.nPartitions);
|
|
1671
1832
|
(_b = (_a = this.jobsRepo).configureJobPartitions) == null ? void 0 : _b.call(_a, this.getJobNames(config.jobs), config.nPartitions);
|
|
1672
1833
|
const workersInstance = this.createWorkersInstanceDefinition(config);
|
|
1673
|
-
|
|
1834
|
+
import_logger5.logger.debug("Starting job scheduler", config);
|
|
1674
1835
|
workersInstance.jobAcquisitionHintProbePromise = this.runJobAcquisitionHintProbeLoop(
|
|
1675
1836
|
config,
|
|
1676
1837
|
workersInstance
|
|
@@ -1687,7 +1848,7 @@ var WorkerService = class {
|
|
|
1687
1848
|
workersInstance.signalStop();
|
|
1688
1849
|
(_a2 = workersInstance.cancelJobAcquisitionHintProbeWait) == null ? void 0 : _a2.call(workersInstance);
|
|
1689
1850
|
(_b2 = workersInstance.cancelPartitionReconcilerWait) == null ? void 0 : _b2.call(workersInstance);
|
|
1690
|
-
|
|
1851
|
+
import_logger5.logger.error("Job scheduler stopped after an unexpected error.", { error });
|
|
1691
1852
|
});
|
|
1692
1853
|
return workersInstance;
|
|
1693
1854
|
}
|