payload 4.0.0-internal.cd69eef → 4.0.0-internal.d1cc1d3
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/admin/RichText.d.ts +1 -1
- package/dist/admin/RichText.d.ts.map +1 -1
- package/dist/admin/RichText.js.map +1 -1
- package/dist/admin/functions/index.d.ts +10 -8
- package/dist/admin/functions/index.d.ts.map +1 -1
- package/dist/admin/functions/index.js.map +1 -1
- package/dist/admin/types.d.ts +2 -2
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/admin/types.js.map +1 -1
- package/dist/auth/endpoints/login.d.ts.map +1 -1
- package/dist/auth/endpoints/login.js +2 -11
- package/dist/auth/endpoints/login.js.map +1 -1
- package/dist/auth/loginWithCookie.d.ts +33 -0
- package/dist/auth/loginWithCookie.d.ts.map +1 -0
- package/dist/auth/loginWithCookie.js +34 -0
- package/dist/auth/loginWithCookie.js.map +1 -0
- package/dist/auth/serverFunctions/cookies.d.ts +47 -0
- package/dist/auth/serverFunctions/cookies.d.ts.map +1 -0
- package/dist/auth/serverFunctions/cookies.js +52 -0
- package/dist/auth/serverFunctions/cookies.js.map +1 -0
- package/dist/auth/serverFunctions/login.d.ts +29 -0
- package/dist/auth/serverFunctions/login.d.ts.map +1 -0
- package/dist/auth/serverFunctions/login.js +63 -0
- package/dist/auth/serverFunctions/login.js.map +1 -0
- package/dist/auth/serverFunctions/logout.d.ts +17 -0
- package/dist/auth/serverFunctions/logout.d.ts.map +1 -0
- package/dist/auth/serverFunctions/logout.js +58 -0
- package/dist/auth/serverFunctions/logout.js.map +1 -0
- package/dist/auth/serverFunctions/refresh.d.ts +17 -0
- package/dist/auth/serverFunctions/refresh.d.ts.map +1 -0
- package/dist/auth/serverFunctions/refresh.js +61 -0
- package/dist/auth/serverFunctions/refresh.js.map +1 -0
- package/dist/collections/config/client.d.ts +2 -3
- package/dist/collections/config/client.d.ts.map +1 -1
- package/dist/collections/config/client.js +5 -7
- package/dist/collections/config/client.js.map +1 -1
- package/dist/collections/config/defaults.d.ts.map +1 -1
- package/dist/collections/config/defaults.js +1 -0
- package/dist/collections/config/defaults.js.map +1 -1
- package/dist/collections/config/sanitize.d.ts +3 -8
- package/dist/collections/config/sanitize.d.ts.map +1 -1
- package/dist/collections/config/sanitize.js +2 -6
- package/dist/collections/config/sanitize.js.map +1 -1
- package/dist/collections/config/types.d.ts +1 -1
- package/dist/collections/config/types.d.ts.map +1 -1
- package/dist/collections/config/types.js.map +1 -1
- package/dist/collections/config/useAsTitle.spec.js +27 -27
- package/dist/collections/config/useAsTitle.spec.js.map +1 -1
- package/dist/collections/operations/create.d.ts.map +1 -1
- package/dist/collections/operations/create.js +10 -0
- package/dist/collections/operations/create.js.map +1 -1
- package/dist/collections/operations/restoreVersion.d.ts.map +1 -1
- package/dist/collections/operations/restoreVersion.js +7 -4
- package/dist/collections/operations/restoreVersion.js.map +1 -1
- package/dist/collections/operations/updateByID.js +1 -0
- package/dist/collections/operations/updateByID.js.map +1 -1
- package/dist/config/build.js +1 -1
- package/dist/config/build.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +5 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/orderable/index.d.ts +1 -1
- package/dist/config/orderable/index.d.ts.map +1 -1
- package/dist/config/orderable/index.js +2 -2
- package/dist/config/orderable/index.js.map +1 -1
- package/dist/config/sanitize.d.ts +1 -1
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +33 -40
- package/dist/config/sanitize.js.map +1 -1
- package/dist/config/types.d.ts +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/database/createDatabaseAdapter.d.ts +1 -1
- package/dist/database/createDatabaseAdapter.d.ts.map +1 -1
- package/dist/database/createDatabaseAdapter.js +0 -2
- package/dist/database/createDatabaseAdapter.js.map +1 -1
- package/dist/database/types.d.ts +6 -0
- package/dist/database/types.d.ts.map +1 -1
- package/dist/database/types.js.map +1 -1
- package/dist/exports/auth.d.ts +5 -0
- package/dist/exports/auth.d.ts.map +1 -0
- package/dist/exports/auth.js +6 -0
- package/dist/exports/auth.js.map +1 -0
- package/dist/exports/internal.d.ts +2 -0
- package/dist/exports/internal.d.ts.map +1 -1
- package/dist/exports/internal.js +3 -1
- package/dist/exports/internal.js.map +1 -1
- package/dist/fields/baseFields/slug/duplicateContext.d.ts +11 -0
- package/dist/fields/baseFields/slug/duplicateContext.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/duplicateContext.js +21 -0
- package/dist/fields/baseFields/slug/duplicateContext.js.map +1 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.d.ts +22 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.js +63 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.js.map +1 -0
- package/dist/fields/baseFields/slug/generateSlug.d.ts +13 -8
- package/dist/fields/baseFields/slug/generateSlug.d.ts.map +1 -1
- package/dist/fields/baseFields/slug/generateSlug.js +98 -45
- package/dist/fields/baseFields/slug/generateSlug.js.map +1 -1
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.d.ts +18 -0
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.js +20 -0
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.js.map +1 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.d.ts +22 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.js +23 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.js.map +1 -0
- package/dist/fields/baseFields/slug/hasValue.d.ts +3 -0
- package/dist/fields/baseFields/slug/hasValue.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/hasValue.js +3 -0
- package/dist/fields/baseFields/slug/hasValue.js.map +1 -0
- package/dist/fields/config/reservedFieldNames.spec.js +18 -18
- package/dist/fields/config/reservedFieldNames.spec.js.map +1 -1
- package/dist/fields/config/sanitize.d.ts +3 -9
- package/dist/fields/config/sanitize.d.ts.map +1 -1
- package/dist/fields/config/sanitize.js +33 -34
- package/dist/fields/config/sanitize.js.map +1 -1
- package/dist/fields/config/sanitize.spec.js +128 -105
- package/dist/fields/config/sanitize.spec.js.map +1 -1
- package/dist/fields/config/types.d.ts +4 -3
- package/dist/fields/config/types.d.ts.map +1 -1
- package/dist/fields/config/types.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.d.ts.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.js +5 -3
- package/dist/fields/hooks/beforeValidate/promise.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/stripNullRows.d.ts +10 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.d.ts.map +1 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.js +18 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.js.map +1 -0
- package/dist/fields/validations.d.ts.map +1 -1
- package/dist/fields/validations.js +7 -8
- package/dist/fields/validations.js.map +1 -1
- package/dist/fields/validations.spec.js +61 -37
- package/dist/fields/validations.spec.js.map +1 -1
- package/dist/globals/config/sanitize.d.ts +2 -7
- package/dist/globals/config/sanitize.d.ts.map +1 -1
- package/dist/globals/config/sanitize.js +2 -6
- package/dist/globals/config/sanitize.js.map +1 -1
- package/dist/globals/config/sanitize.spec.js +6 -6
- package/dist/globals/config/sanitize.spec.js.map +1 -1
- package/dist/globals/operations/countGlobalVersions.d.ts.map +1 -1
- package/dist/globals/operations/countGlobalVersions.js +1 -0
- package/dist/globals/operations/countGlobalVersions.js.map +1 -1
- package/dist/index.bundled.d.ts +247 -178
- package/dist/index.d.ts +49 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/query-presets/constraints.js +1 -1
- package/dist/query-presets/constraints.js.map +1 -1
- package/dist/queues/config/collection.d.ts.map +1 -1
- package/dist/queues/config/collection.js +37 -43
- package/dist/queues/config/collection.js.map +1 -1
- package/dist/queues/config/global.d.ts +5 -6
- package/dist/queues/config/global.d.ts.map +1 -1
- package/dist/queues/config/global.js +1 -1
- package/dist/queues/config/global.js.map +1 -1
- package/dist/queues/config/types/index.d.ts +29 -24
- package/dist/queues/config/types/index.d.ts.map +1 -1
- package/dist/queues/config/types/index.js.map +1 -1
- package/dist/queues/config/types/taskTypes.d.ts +4 -7
- package/dist/queues/config/types/taskTypes.d.ts.map +1 -1
- package/dist/queues/config/types/taskTypes.js.map +1 -1
- package/dist/queues/config/types/workflowJSONTypes.d.ts +10 -9
- package/dist/queues/config/types/workflowJSONTypes.d.ts.map +1 -1
- package/dist/queues/config/types/workflowJSONTypes.js.map +1 -1
- package/dist/queues/config/types/workflowTypes.d.ts +11 -58
- package/dist/queues/config/types/workflowTypes.d.ts.map +1 -1
- package/dist/queues/config/types/workflowTypes.js.map +1 -1
- package/dist/queues/endpoints/handleSchedules.js +1 -1
- package/dist/queues/endpoints/handleSchedules.js.map +1 -1
- package/dist/queues/errors/handleTaskError.js +4 -4
- package/dist/queues/errors/handleTaskError.js.map +1 -1
- package/dist/queues/errors/handleWorkflowError.js +1 -1
- package/dist/queues/errors/handleWorkflowError.js.map +1 -1
- package/dist/queues/errors/index.d.ts +6 -0
- package/dist/queues/errors/index.d.ts.map +1 -1
- package/dist/queues/errors/index.js +5 -0
- package/dist/queues/errors/index.js.map +1 -1
- package/dist/queues/localAPI.d.ts +4 -4
- package/dist/queues/localAPI.d.ts.map +1 -1
- package/dist/queues/localAPI.js +63 -66
- package/dist/queues/localAPI.js.map +1 -1
- package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.d.ts +4 -4
- package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.d.ts.map +1 -1
- package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.js.map +1 -1
- package/dist/queues/operations/handleSchedules/index.d.ts +1 -1
- package/dist/queues/operations/handleSchedules/index.d.ts.map +1 -1
- package/dist/queues/operations/handleSchedules/index.js +1 -1
- package/dist/queues/operations/handleSchedules/index.js.map +1 -1
- package/dist/queues/operations/runJobs/heartbeat.d.ts +13 -0
- package/dist/queues/operations/runJobs/heartbeat.d.ts.map +1 -0
- package/dist/queues/operations/runJobs/heartbeat.js +66 -0
- package/dist/queues/operations/runJobs/heartbeat.js.map +1 -0
- package/dist/queues/operations/runJobs/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/index.js +133 -84
- package/dist/queues/operations/runJobs/index.js.map +1 -1
- package/dist/queues/operations/runJobs/runJSONJob/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJSONJob/index.js +6 -3
- package/dist/queues/operations/runJobs/runJSONJob/index.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js +5 -5
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.d.ts +2 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.js +39 -8
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/importHandlerPath.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJob/index.js +4 -4
- package/dist/queues/operations/runJobs/runJob/index.js.map +1 -1
- package/dist/queues/utilities/updateJob.d.ts.map +1 -1
- package/dist/queues/utilities/updateJob.js +3 -0
- package/dist/queues/utilities/updateJob.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/uploads/checkFileRestrictions.d.ts +1 -1
- package/dist/uploads/checkFileRestrictions.d.ts.map +1 -1
- package/dist/uploads/checkFileRestrictions.js +15 -1
- package/dist/uploads/checkFileRestrictions.js.map +1 -1
- package/dist/uploads/endpoints/uploadInstructions.d.ts +12 -0
- package/dist/uploads/endpoints/uploadInstructions.d.ts.map +1 -1
- package/dist/uploads/endpoints/uploadInstructions.js +66 -20
- package/dist/uploads/endpoints/uploadInstructions.js.map +1 -1
- package/dist/uploads/generateFileData.js +4 -1
- package/dist/uploads/generateFileData.js.map +1 -1
- package/dist/uploads/getFileFromUploadInstructions.d.ts +8 -0
- package/dist/uploads/getFileFromUploadInstructions.d.ts.map +1 -0
- package/dist/uploads/getFileFromUploadInstructions.js +62 -0
- package/dist/uploads/getFileFromUploadInstructions.js.map +1 -0
- package/dist/uploads/getImageSize.d.ts +12 -1
- package/dist/uploads/getImageSize.d.ts.map +1 -1
- package/dist/uploads/getImageSize.js +20 -18
- package/dist/uploads/getImageSize.js.map +1 -1
- package/dist/uploads/getImageSize.spec.js +298 -0
- package/dist/uploads/getImageSize.spec.js.map +1 -0
- package/dist/uploads/probeImageSize.d.ts +39 -0
- package/dist/uploads/probeImageSize.d.ts.map +1 -0
- package/dist/uploads/probeImageSize.js +374 -0
- package/dist/uploads/probeImageSize.js.map +1 -0
- package/dist/uploads/probeImageSize.spec.js +366 -0
- package/dist/uploads/probeImageSize.spec.js.map +1 -0
- package/dist/uploads/stagedUpload.d.ts +27 -0
- package/dist/uploads/stagedUpload.d.ts.map +1 -0
- package/dist/uploads/stagedUpload.js +197 -0
- package/dist/uploads/stagedUpload.js.map +1 -0
- package/dist/uploads/types.d.ts +41 -13
- package/dist/uploads/types.d.ts.map +1 -1
- package/dist/uploads/types.js.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.js +12 -46
- package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
- package/dist/utilities/configToJSONSchema.spec.js +33 -33
- package/dist/utilities/configToJSONSchema.spec.js.map +1 -1
- package/dist/utilities/fieldValueExists.d.ts +29 -0
- package/dist/utilities/fieldValueExists.d.ts.map +1 -0
- package/dist/utilities/fieldValueExists.js +27 -0
- package/dist/utilities/fieldValueExists.js.map +1 -0
- package/dist/utilities/getUniqueFieldValue.d.ts +27 -0
- package/dist/utilities/getUniqueFieldValue.d.ts.map +1 -0
- package/dist/utilities/getUniqueFieldValue.js +26 -0
- package/dist/utilities/getUniqueFieldValue.js.map +1 -0
- package/dist/versions/deleteScheduledPublishJobs.js +2 -2
- package/dist/versions/deleteScheduledPublishJobs.js.map +1 -1
- package/dist/versions/payloadPackageList.d.ts.map +1 -1
- package/dist/versions/payloadPackageList.js +0 -1
- package/dist/versions/payloadPackageList.js.map +1 -1
- package/package.json +8 -3
- package/dist/database/defaultUpdateJobs.d.ts +0 -3
- package/dist/database/defaultUpdateJobs.d.ts.map +0 -1
- package/dist/database/defaultUpdateJobs.js +0 -41
- package/dist/database/defaultUpdateJobs.js.map +0 -1
- package/dist/fields/baseFields/slug/countVersions.d.ts +0 -13
- package/dist/fields/baseFields/slug/countVersions.d.ts.map +0 -1
- package/dist/fields/baseFields/slug/countVersions.js +0 -27
- package/dist/fields/baseFields/slug/countVersions.js.map +0 -1
- package/dist/uploads/tempFile.d.ts +0 -7
- package/dist/uploads/tempFile.d.ts.map +0 -1
- package/dist/uploads/tempFile.js +0 -39
- package/dist/uploads/tempFile.js.map +0 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { v4 as uuid } from 'uuid';
|
|
1
2
|
import { Forbidden } from '../../../errors/Forbidden.js';
|
|
2
3
|
import { isolateObjectProperty } from '../../../utilities/isolateObjectProperty.js';
|
|
3
4
|
import { jobsCollectionSlug } from '../../config/collection.js';
|
|
4
|
-
import { JobCancelledError } from '../../errors/index.js';
|
|
5
|
+
import { JobCancelledError, JobRunAbortedError } from '../../errors/index.js';
|
|
5
6
|
import { getCurrentDate } from '../../utilities/getCurrentDate.js';
|
|
6
|
-
import {
|
|
7
|
+
import { updateJobs } from '../../utilities/updateJob.js';
|
|
8
|
+
import { startProcessingLeaseHeartbeat } from './heartbeat.js';
|
|
7
9
|
import { getUpdateJobFunction } from './runJob/getUpdateJobFunction.js';
|
|
8
10
|
import { importHandlerPath } from './runJob/importHandlerPath.js';
|
|
9
11
|
import { runJob } from './runJob/index.js';
|
|
@@ -21,6 +23,11 @@ export const runJobs = async (args)=>{
|
|
|
21
23
|
throw new Forbidden(req.t);
|
|
22
24
|
}
|
|
23
25
|
}
|
|
26
|
+
const now = getCurrentDate();
|
|
27
|
+
const { duration: processingLeaseDuration, safetyBuffer: processingLeaseSafetyBuffer } = jobsConfig.processingLease;
|
|
28
|
+
const nowISOString = now.toISOString();
|
|
29
|
+
const processingUntil = new Date(now.getTime() + processingLeaseDuration).toISOString();
|
|
30
|
+
const processingToken = uuid();
|
|
24
31
|
const and = [
|
|
25
32
|
{
|
|
26
33
|
completedAt: {
|
|
@@ -33,9 +40,18 @@ export const runJobs = async (args)=>{
|
|
|
33
40
|
}
|
|
34
41
|
},
|
|
35
42
|
{
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
or: [
|
|
44
|
+
{
|
|
45
|
+
processingUntil: {
|
|
46
|
+
exists: false
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
processingUntil: {
|
|
51
|
+
less_than_equal: nowISOString
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
]
|
|
39
55
|
},
|
|
40
56
|
{
|
|
41
57
|
or: [
|
|
@@ -46,13 +62,13 @@ export const runJobs = async (args)=>{
|
|
|
46
62
|
},
|
|
47
63
|
{
|
|
48
64
|
waitUntil: {
|
|
49
|
-
less_than:
|
|
65
|
+
less_than: nowISOString
|
|
50
66
|
}
|
|
51
67
|
}
|
|
52
68
|
]
|
|
53
69
|
}
|
|
54
70
|
];
|
|
55
|
-
if (allQueues !== true) {
|
|
71
|
+
if (!id && allQueues !== true) {
|
|
56
72
|
and.push({
|
|
57
73
|
queue: {
|
|
58
74
|
equals: queue ?? 'default'
|
|
@@ -62,10 +78,16 @@ export const runJobs = async (args)=>{
|
|
|
62
78
|
if (whereFromProps) {
|
|
63
79
|
and.push(whereFromProps);
|
|
64
80
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
if (id) {
|
|
82
|
+
and.push({
|
|
83
|
+
id: {
|
|
84
|
+
equals: id
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (jobsConfig.hasConcurrency) {
|
|
89
|
+
// Find currently running jobs with concurrency keys to enforce exclusive concurrency.
|
|
90
|
+
// Jobs with the same concurrencyKey should not run in parallel.
|
|
69
91
|
const runningJobsWithConcurrency = await payload.db.find({
|
|
70
92
|
collection: jobsCollectionSlug,
|
|
71
93
|
limit: 0,
|
|
@@ -79,8 +101,8 @@ export const runJobs = async (args)=>{
|
|
|
79
101
|
where: {
|
|
80
102
|
and: [
|
|
81
103
|
{
|
|
82
|
-
|
|
83
|
-
|
|
104
|
+
processingUntil: {
|
|
105
|
+
greater_than: nowISOString
|
|
84
106
|
}
|
|
85
107
|
},
|
|
86
108
|
{
|
|
@@ -122,23 +144,24 @@ export const runJobs = async (args)=>{
|
|
|
122
144
|
});
|
|
123
145
|
}
|
|
124
146
|
}
|
|
125
|
-
//
|
|
126
|
-
//
|
|
147
|
+
// Claim jobs before running them so another worker cannot pick up the same jobs.
|
|
148
|
+
// `processingToken` identifies which jobs were claimed by this runner.
|
|
127
149
|
let jobs = [];
|
|
128
150
|
if (id) {
|
|
129
|
-
|
|
130
|
-
const job = await updateJob({
|
|
131
|
-
id,
|
|
151
|
+
const updatedDocs = await updateJobs({
|
|
132
152
|
data: {
|
|
133
|
-
|
|
153
|
+
processingToken,
|
|
154
|
+
processingUntil
|
|
134
155
|
},
|
|
156
|
+
limit: 1,
|
|
135
157
|
req,
|
|
136
|
-
returning: true
|
|
158
|
+
returning: true,
|
|
159
|
+
where: {
|
|
160
|
+
and
|
|
161
|
+
}
|
|
137
162
|
});
|
|
138
|
-
if (
|
|
139
|
-
jobs =
|
|
140
|
-
job
|
|
141
|
-
];
|
|
163
|
+
if (updatedDocs) {
|
|
164
|
+
jobs = updatedDocs;
|
|
142
165
|
}
|
|
143
166
|
} else {
|
|
144
167
|
let defaultProcessingOrder = payload.collections[jobsCollectionSlug]?.config.defaultSort ?? 'createdAt';
|
|
@@ -156,7 +179,8 @@ export const runJobs = async (args)=>{
|
|
|
156
179
|
}
|
|
157
180
|
const updatedDocs = await updateJobs({
|
|
158
181
|
data: {
|
|
159
|
-
|
|
182
|
+
processingToken,
|
|
183
|
+
processingUntil
|
|
160
184
|
},
|
|
161
185
|
limit,
|
|
162
186
|
req,
|
|
@@ -176,10 +200,9 @@ export const runJobs = async (args)=>{
|
|
|
176
200
|
remainingJobsFromQueried: 0
|
|
177
201
|
};
|
|
178
202
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
//
|
|
182
|
-
// We should only run one job per concurrencyKey, release the others back to pending
|
|
203
|
+
if (jobsConfig.hasConcurrency) {
|
|
204
|
+
// Handle the case where multiple jobs with the same concurrencyKey were picked up in the same batch.
|
|
205
|
+
// We should only run one job per concurrencyKey, releasing the others back to pending.
|
|
183
206
|
const seenConcurrencyKeys = new Set();
|
|
184
207
|
const jobsToRun = [];
|
|
185
208
|
const jobsToRelease = [];
|
|
@@ -201,25 +224,39 @@ export const runJobs = async (args)=>{
|
|
|
201
224
|
const releaseIds = jobsToRelease.map((job)=>job.id);
|
|
202
225
|
await updateJobs({
|
|
203
226
|
data: {
|
|
204
|
-
|
|
227
|
+
processingUntil: null
|
|
205
228
|
},
|
|
206
229
|
req,
|
|
207
230
|
returning: false,
|
|
208
231
|
where: {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
232
|
+
and: [
|
|
233
|
+
{
|
|
234
|
+
id: {
|
|
235
|
+
in: releaseIds
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
processingToken: {
|
|
240
|
+
equals: processingToken
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
processingUntil: {
|
|
245
|
+
greater_than: new Date(getCurrentDate().getTime() + processingLeaseSafetyBuffer).toISOString()
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
]
|
|
212
249
|
}
|
|
213
250
|
});
|
|
214
251
|
}
|
|
215
252
|
// Use only the filtered jobs going forward
|
|
216
253
|
jobs = jobsToRun;
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
254
|
+
if (!jobs.length) {
|
|
255
|
+
return {
|
|
256
|
+
noJobsRemaining: false,
|
|
257
|
+
remainingJobsFromQueried: 0
|
|
258
|
+
};
|
|
259
|
+
}
|
|
223
260
|
}
|
|
224
261
|
if (!silent || typeof silent === 'object' && !silent.info) {
|
|
225
262
|
let newCount = 0;
|
|
@@ -259,31 +296,31 @@ export const runJobs = async (args)=>{
|
|
|
259
296
|
};
|
|
260
297
|
}
|
|
261
298
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
299
|
+
try {
|
|
300
|
+
if (!workflowConfig) {
|
|
301
|
+
// Permanently fail jobs whose task/workflow slug is no longer registered in config — they can never complete.
|
|
302
|
+
const errorMessage = `${job.taskSlug ? `Task '${job.taskSlug}'` : `Workflow '${job.workflowSlug}'`} is not registered in payload.config.jobs.`;
|
|
303
|
+
if (!silent || typeof silent === 'object' && !silent.error) {
|
|
304
|
+
payload.logger.error({
|
|
305
|
+
msg: `Error running job ${job.workflowSlug || `Task: ${job.taskSlug}`} id: ${job.id} - ${errorMessage}`
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
const updateJob = getUpdateJobFunction(job, jobReq);
|
|
309
|
+
await updateJob({
|
|
310
|
+
error: {
|
|
311
|
+
message: errorMessage
|
|
312
|
+
},
|
|
313
|
+
hasError: true,
|
|
314
|
+
processingUntil: null,
|
|
315
|
+
totalTried: (job.totalTried ?? 0) + 1
|
|
268
316
|
});
|
|
317
|
+
return {
|
|
318
|
+
id: job.id,
|
|
319
|
+
result: {
|
|
320
|
+
status: 'error-reached-max-retries'
|
|
321
|
+
}
|
|
322
|
+
};
|
|
269
323
|
}
|
|
270
|
-
const updateJob = getUpdateJobFunction(job, jobReq);
|
|
271
|
-
await updateJob({
|
|
272
|
-
error: {
|
|
273
|
-
message: errorMessage
|
|
274
|
-
},
|
|
275
|
-
hasError: true,
|
|
276
|
-
processing: false,
|
|
277
|
-
totalTried: (job.totalTried ?? 0) + 1
|
|
278
|
-
});
|
|
279
|
-
return {
|
|
280
|
-
id: job.id,
|
|
281
|
-
result: {
|
|
282
|
-
status: 'error-reached-max-retries'
|
|
283
|
-
}
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
try {
|
|
287
324
|
const updateJob = getUpdateJobFunction(job, jobReq);
|
|
288
325
|
// the runner will either be passed to the config
|
|
289
326
|
// OR it will be a path, which we will need to import via eval to avoid
|
|
@@ -304,7 +341,7 @@ export const runJobs = async (args)=>{
|
|
|
304
341
|
error: errorMessage
|
|
305
342
|
},
|
|
306
343
|
hasError: true,
|
|
307
|
-
|
|
344
|
+
processingUntil: null
|
|
308
345
|
});
|
|
309
346
|
return {
|
|
310
347
|
id: job.id,
|
|
@@ -348,24 +385,24 @@ export const runJobs = async (args)=>{
|
|
|
348
385
|
};
|
|
349
386
|
}
|
|
350
387
|
} catch (error) {
|
|
388
|
+
if (error instanceof JobRunAbortedError) {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
351
391
|
if (error instanceof JobCancelledError) {
|
|
352
|
-
if (!job.error?.cancelled || !job.hasError || job.
|
|
392
|
+
if (!job.error?.cancelled || !job.hasError || job.processingUntil || job.completedAt || job.waitUntil) {
|
|
353
393
|
// When using the local API to cancel jobs, the local API will update the job data for us to ensure the job is cancelled.
|
|
354
394
|
// But when throwing a JobCancelledError within a task or workflow handler, we are responsible for updating the job data ourselves.
|
|
395
|
+
// Use the lease-protected getUpdateJobFunction so an old worker cannot cancel the job after another worker claims it.
|
|
396
|
+
const updateJob = getUpdateJobFunction(job, jobReq);
|
|
355
397
|
await updateJob({
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
cancelled: true,
|
|
361
|
-
message: error.message
|
|
362
|
-
},
|
|
363
|
-
hasError: true,
|
|
364
|
-
processing: false,
|
|
365
|
-
waitUntil: null
|
|
398
|
+
completedAt: null,
|
|
399
|
+
error: {
|
|
400
|
+
cancelled: true,
|
|
401
|
+
message: error.message
|
|
366
402
|
},
|
|
367
|
-
|
|
368
|
-
|
|
403
|
+
hasError: true,
|
|
404
|
+
processingUntil: null,
|
|
405
|
+
waitUntil: null
|
|
369
406
|
});
|
|
370
407
|
}
|
|
371
408
|
return {
|
|
@@ -378,17 +415,29 @@ export const runJobs = async (args)=>{
|
|
|
378
415
|
throw error;
|
|
379
416
|
}
|
|
380
417
|
};
|
|
418
|
+
const stopHeartbeat = startProcessingLeaseHeartbeat({
|
|
419
|
+
jobIDs: jobs.map((job)=>job.id),
|
|
420
|
+
processingLeaseDuration,
|
|
421
|
+
processingLeaseSafetyBuffer,
|
|
422
|
+
processingToken,
|
|
423
|
+
req,
|
|
424
|
+
silent
|
|
425
|
+
});
|
|
381
426
|
let resultsArray = [];
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
|
|
427
|
+
try {
|
|
428
|
+
if (sequential) {
|
|
429
|
+
for (const job of jobs){
|
|
430
|
+
const result = await runSingleJob(job);
|
|
431
|
+
if (result) {
|
|
432
|
+
resultsArray.push(result);
|
|
433
|
+
}
|
|
387
434
|
}
|
|
435
|
+
} else {
|
|
436
|
+
const jobPromises = jobs.map(runSingleJob);
|
|
437
|
+
resultsArray = (await Promise.all(jobPromises)).filter((result)=>result !== null);
|
|
388
438
|
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
resultsArray = await Promise.all(jobPromises);
|
|
439
|
+
} finally{
|
|
440
|
+
stopHeartbeat();
|
|
392
441
|
}
|
|
393
442
|
if (jobsConfig.deleteJobOnComplete && successfullyCompletedJobs.length) {
|
|
394
443
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/queues/operations/runJobs/index.ts"],"sourcesContent":["import type { Job } from '../../../index.js'\nimport type { PayloadRequest, Sort, Where } from '../../../types/index.js'\nimport type { WorkflowJSON } from '../../config/types/workflowJSONTypes.js'\nimport type { WorkflowConfig, WorkflowHandler } from '../../config/types/workflowTypes.js'\nimport type { RunJobsSilent } from '../../localAPI.js'\nimport type { RunJobResult } from './runJob/index.js'\n\nimport { Forbidden } from '../../../errors/Forbidden.js'\nimport { isolateObjectProperty } from '../../../utilities/isolateObjectProperty.js'\nimport { jobsCollectionSlug } from '../../config/collection.js'\nimport { JobCancelledError } from '../../errors/index.js'\nimport { getCurrentDate } from '../../utilities/getCurrentDate.js'\nimport { updateJob, updateJobs } from '../../utilities/updateJob.js'\nimport { getUpdateJobFunction } from './runJob/getUpdateJobFunction.js'\nimport { importHandlerPath } from './runJob/importHandlerPath.js'\nimport { runJob } from './runJob/index.js'\nimport { runJSONJob } from './runJSONJob/index.js'\n\nexport type RunJobsArgs = {\n /**\n * If you want to run jobs from all queues, set this to true.\n * If you set this to true, the `queue` property will be ignored.\n *\n * @default false\n */\n allQueues?: boolean\n /**\n * ID of the job to run\n */\n id?: number | string\n /**\n * The maximum number of jobs to run in this invocation\n *\n * @default 10\n */\n limit?: number\n overrideAccess?: boolean\n /**\n * Adjust the job processing order\n *\n * FIFO would equal `createdAt` and LIFO would equal `-createdAt`.\n *\n * @default all jobs for all queues will be executed in FIFO order.\n */\n processingOrder?: Sort\n /**\n * If you want to run jobs from a specific queue, set this to the queue name.\n *\n * @default jobs from the `default` queue will be executed.\n */\n queue?: string\n req: PayloadRequest\n /**\n * By default, jobs are run in parallel.\n * If you want to run them in sequence, set this to true.\n */\n sequential?: boolean\n /**\n * If set to true, the job system will not log any output to the console (for both info and error logs).\n * Can be an option for more granular control over logging.\n *\n * This will not automatically affect user-configured logs (e.g. if you call `console.log` or `payload.logger.info` in your job code).\n *\n * @default false\n */\n silent?: RunJobsSilent\n where?: Where\n}\n\nexport type RunJobsResult = {\n jobStatus?: Record<string, RunJobResult>\n /**\n * If this is true, there for sure are no jobs remaining, regardless of the limit\n */\n noJobsRemaining?: boolean\n /**\n * Out of the jobs that were queried & processed (within the set limit), how many are remaining and retryable?\n */\n remainingJobsFromQueried: number\n}\n\nexport const runJobs = async (args: RunJobsArgs): Promise<RunJobsResult> => {\n const {\n id,\n allQueues = false,\n limit = 10,\n overrideAccess,\n processingOrder,\n queue = 'default',\n req,\n req: {\n payload,\n payload: {\n config: { jobs: jobsConfig },\n },\n },\n sequential,\n silent = false,\n where: whereFromProps,\n } = args\n\n if (!overrideAccess) {\n /**\n * By default, jobsConfig.access.run will be `defaultAccess` which is a function that returns `true` if the user is logged in.\n */\n const accessFn = jobsConfig?.access?.run ?? (() => true)\n const hasAccess = await accessFn({ req })\n if (!hasAccess) {\n throw new Forbidden(req.t)\n }\n }\n const and: Where[] = [\n {\n completedAt: {\n exists: false,\n },\n },\n {\n hasError: {\n not_equals: true,\n },\n },\n {\n processing: {\n equals: false,\n },\n },\n {\n or: [\n {\n waitUntil: {\n exists: false,\n },\n },\n {\n waitUntil: {\n less_than: getCurrentDate().toISOString(),\n },\n },\n ],\n },\n ]\n\n if (allQueues !== true) {\n and.push({\n queue: {\n equals: queue ?? 'default',\n },\n })\n }\n\n if (whereFromProps) {\n and.push(whereFromProps)\n }\n\n // Only enforce concurrency controls if the feature is enabled\n if (jobsConfig.enableConcurrencyControl) {\n // Find currently running jobs with concurrency keys to enforce exclusive concurrency\n // Jobs with the same concurrencyKey should not run in parallel\n const runningJobsWithConcurrency = await payload.db.find({\n collection: jobsCollectionSlug,\n limit: 0,\n pagination: false,\n req: { transactionID: undefined },\n select: {\n concurrencyKey: true,\n },\n where: {\n and: [{ processing: { equals: true } }, { concurrencyKey: { exists: true } }],\n },\n })\n\n const runningConcurrencyKeys = new Set<string>()\n if (runningJobsWithConcurrency?.docs) {\n for (const doc of runningJobsWithConcurrency.docs) {\n const concurrencyKey = (doc as Job).concurrencyKey\n if (concurrencyKey) {\n runningConcurrencyKeys.add(concurrencyKey)\n }\n }\n }\n\n // Exclude jobs whose concurrencyKey is already running\n if (runningConcurrencyKeys.size > 0) {\n and.push({\n or: [\n // Jobs without a concurrency key can always run\n { concurrencyKey: { exists: false } },\n // Jobs with a concurrency key that is not currently running can run\n { concurrencyKey: { not_in: [...runningConcurrencyKeys] } },\n ],\n })\n }\n }\n\n // Find all jobs and ensure we set job to processing: true as early as possible to reduce the chance of\n // the same job being picked up by another worker\n let jobs: Job[] = []\n\n if (id) {\n // Only one job to run\n const job = await updateJob({\n id,\n data: {\n processing: true,\n },\n req,\n returning: true,\n })\n if (job) {\n jobs = [job]\n }\n } else {\n let defaultProcessingOrder: Sort =\n payload.collections[jobsCollectionSlug]?.config.defaultSort ?? 'createdAt'\n\n const processingOrderConfig = jobsConfig.processingOrder\n if (typeof processingOrderConfig === 'function') {\n defaultProcessingOrder = await processingOrderConfig(args)\n } else if (typeof processingOrderConfig === 'object' && !Array.isArray(processingOrderConfig)) {\n if (\n !allQueues &&\n queue &&\n processingOrderConfig.queues &&\n processingOrderConfig.queues[queue]\n ) {\n defaultProcessingOrder = processingOrderConfig.queues[queue]\n } else if (processingOrderConfig.default) {\n defaultProcessingOrder = processingOrderConfig.default\n }\n } else if (typeof processingOrderConfig === 'string') {\n defaultProcessingOrder = processingOrderConfig\n }\n const updatedDocs = await updateJobs({\n data: {\n processing: true,\n },\n limit,\n req,\n returning: true,\n sort: processingOrder ?? defaultProcessingOrder,\n where: { and },\n })\n\n if (updatedDocs) {\n jobs = updatedDocs\n }\n }\n\n if (!jobs.length) {\n return {\n noJobsRemaining: true,\n remainingJobsFromQueried: 0,\n }\n }\n\n // Only handle concurrency deduplication if the feature is enabled\n if (jobsConfig.enableConcurrencyControl) {\n // Handle the case where multiple jobs with the same concurrencyKey were picked up in the same batch\n // We should only run one job per concurrencyKey, release the others back to pending\n const seenConcurrencyKeys = new Set<string>()\n const jobsToRun: Job[] = []\n const jobsToRelease: Job[] = []\n\n for (const job of jobs) {\n if (job.concurrencyKey) {\n if (seenConcurrencyKeys.has(job.concurrencyKey)) {\n // This job has the same concurrencyKey as another job we're already running\n jobsToRelease.push(job)\n } else {\n seenConcurrencyKeys.add(job.concurrencyKey)\n jobsToRun.push(job)\n }\n } else {\n jobsToRun.push(job)\n }\n }\n\n // Release duplicate concurrencyKey jobs back to pending state\n if (jobsToRelease.length > 0) {\n const releaseIds = jobsToRelease.map((job) => job.id)\n await updateJobs({\n data: { processing: false },\n req,\n returning: false,\n where: { id: { in: releaseIds } },\n })\n }\n\n // Use only the filtered jobs going forward\n jobs = jobsToRun\n }\n\n if (!jobs.length) {\n return {\n noJobsRemaining: false,\n remainingJobsFromQueried: 0,\n }\n }\n\n if (!silent || (typeof silent === 'object' && !silent.info)) {\n let newCount = 0\n let retryCount = 0\n\n for (const job of jobs) {\n if (job.totalTried > 0) {\n retryCount++\n } else {\n newCount++\n }\n }\n\n payload.logger.info({\n msg: `Running ${jobs.length} jobs.`,\n new: newCount,\n retrying: retryCount,\n })\n }\n\n const successfullyCompletedJobs: (number | string)[] = []\n\n const runSingleJob = async (\n job: Job,\n ): Promise<{\n id: number | string\n result: RunJobResult\n }> => {\n if (!job.workflowSlug && !job.taskSlug) {\n throw new Error('Job must have either a workflowSlug or a taskSlug')\n }\n const jobReq = isolateObjectProperty(req, 'transactionID')\n\n let workflowConfig: undefined | WorkflowConfig = undefined\n\n if (job.workflowSlug && jobsConfig.workflows?.length) {\n workflowConfig = jobsConfig.workflows.find(({ slug }) => slug === job.workflowSlug)\n } else if (job.taskSlug && jobsConfig.tasks?.length) {\n const taskExists = jobsConfig.tasks.some(({ slug }) => slug === job.taskSlug)\n if (taskExists) {\n workflowConfig = {\n slug: 'singleTask',\n handler: async ({ job, tasks }) => {\n await tasks[job.taskSlug as string]!('1', {\n input: job.input,\n })\n },\n }\n }\n }\n\n if (!workflowConfig) {\n // Permanently fail jobs whose task/workflow slug is no longer registered in config — they can never complete.\n const errorMessage = `${job.taskSlug ? `Task '${job.taskSlug}'` : `Workflow '${job.workflowSlug}'`} is not registered in payload.config.jobs.`\n\n if (!silent || (typeof silent === 'object' && !silent.error)) {\n payload.logger.error({\n msg: `Error running job ${job.workflowSlug || `Task: ${job.taskSlug}`} id: ${job.id} - ${errorMessage}`,\n })\n }\n\n const updateJob = getUpdateJobFunction(job, jobReq)\n await updateJob({\n error: { message: errorMessage },\n hasError: true,\n processing: false,\n totalTried: (job.totalTried ?? 0) + 1,\n })\n\n return {\n id: job.id,\n result: {\n status: 'error-reached-max-retries',\n },\n }\n }\n\n try {\n const updateJob = getUpdateJobFunction(job, jobReq)\n\n // the runner will either be passed to the config\n // OR it will be a path, which we will need to import via eval to avoid\n // Next.js compiler dynamic import expression errors\n let workflowHandler: WorkflowHandler | WorkflowJSON\n if (\n typeof workflowConfig.handler === 'function' ||\n (typeof workflowConfig.handler === 'object' && Array.isArray(workflowConfig.handler))\n ) {\n workflowHandler = workflowConfig.handler\n } else {\n workflowHandler = await importHandlerPath<typeof workflowHandler>(workflowConfig.handler)\n\n if (!workflowHandler) {\n const jobLabel = job.workflowSlug || `Task: ${job.taskSlug}`\n const errorMessage = `Can't find runner while importing with the path ${workflowConfig.handler} in job type ${jobLabel}.`\n if (!silent || (typeof silent === 'object' && !silent.error)) {\n payload.logger.error(errorMessage)\n }\n\n await updateJob({\n error: {\n error: errorMessage,\n },\n hasError: true,\n processing: false,\n })\n\n return {\n id: job.id,\n result: {\n status: 'error-reached-max-retries',\n },\n }\n }\n }\n\n if (typeof workflowHandler === 'function') {\n const result = await runJob({\n job,\n req: jobReq,\n silent,\n updateJob,\n workflowConfig,\n workflowHandler,\n })\n\n if (result.status === 'success') {\n successfullyCompletedJobs.push(job.id)\n }\n\n return { id: job.id, result }\n } else {\n const result = await runJSONJob({\n job,\n req: jobReq,\n silent,\n updateJob,\n workflowConfig,\n workflowHandler,\n })\n\n if (result.status === 'success') {\n successfullyCompletedJobs.push(job.id)\n }\n\n return { id: job.id, result }\n }\n } catch (error) {\n if (error instanceof JobCancelledError) {\n if (\n !(job.error as Record<string, unknown> | undefined)?.cancelled ||\n !job.hasError ||\n job.processing ||\n job.completedAt ||\n job.waitUntil\n ) {\n // When using the local API to cancel jobs, the local API will update the job data for us to ensure the job is cancelled.\n // But when throwing a JobCancelledError within a task or workflow handler, we are responsible for updating the job data ourselves.\n await updateJob({\n id: job.id,\n data: {\n completedAt: null,\n error: {\n cancelled: true,\n message: error.message,\n },\n hasError: true,\n processing: false,\n waitUntil: null,\n },\n req,\n returning: false,\n })\n }\n\n return {\n id: job.id,\n result: {\n status: 'error-reached-max-retries',\n },\n }\n }\n throw error\n }\n }\n\n let resultsArray: { id: number | string; result: RunJobResult }[] = []\n if (sequential) {\n for (const job of jobs) {\n const result = await runSingleJob(job)\n if (result) {\n resultsArray.push(result)\n }\n }\n } else {\n const jobPromises = jobs.map(runSingleJob)\n resultsArray = (await Promise.all(jobPromises)) as {\n id: number | string\n result: RunJobResult\n }[]\n }\n\n if (jobsConfig.deleteJobOnComplete && successfullyCompletedJobs.length) {\n try {\n await payload.db.deleteMany({\n collection: jobsCollectionSlug,\n where: { id: { in: successfullyCompletedJobs } },\n })\n } catch (err) {\n if (!silent || (typeof silent === 'object' && !silent.error)) {\n payload.logger.error({\n err,\n msg: `Failed to delete jobs ${successfullyCompletedJobs.join(', ')} on complete`,\n })\n }\n }\n }\n\n const resultsObject: RunJobsResult['jobStatus'] = resultsArray.reduce(\n (acc, cur) => {\n if (cur !== null) {\n // Check if there's a valid result to include\n acc[cur.id] = cur.result\n }\n return acc\n },\n {} as Record<string, RunJobResult>,\n )\n\n let remainingJobsFromQueried = 0\n for (const jobID in resultsObject) {\n const jobResult = resultsObject[jobID]\n if (jobResult?.status === 'error') {\n remainingJobsFromQueried++ // Can be retried\n }\n }\n\n return {\n jobStatus: resultsObject,\n remainingJobsFromQueried,\n }\n}\n"],"names":["Forbidden","isolateObjectProperty","jobsCollectionSlug","JobCancelledError","getCurrentDate","updateJob","updateJobs","getUpdateJobFunction","importHandlerPath","runJob","runJSONJob","runJobs","args","id","allQueues","limit","overrideAccess","processingOrder","queue","req","payload","config","jobs","jobsConfig","sequential","silent","where","whereFromProps","accessFn","access","run","hasAccess","t","and","completedAt","exists","hasError","not_equals","processing","equals","or","waitUntil","less_than","toISOString","push","enableConcurrencyControl","runningJobsWithConcurrency","db","find","collection","pagination","transactionID","undefined","select","concurrencyKey","runningConcurrencyKeys","Set","docs","doc","add","size","not_in","job","data","returning","defaultProcessingOrder","collections","defaultSort","processingOrderConfig","Array","isArray","queues","default","updatedDocs","sort","length","noJobsRemaining","remainingJobsFromQueried","seenConcurrencyKeys","jobsToRun","jobsToRelease","has","releaseIds","map","in","info","newCount","retryCount","totalTried","logger","msg","new","retrying","successfullyCompletedJobs","runSingleJob","workflowSlug","taskSlug","Error","jobReq","workflowConfig","workflows","slug","tasks","taskExists","some","handler","input","errorMessage","error","message","result","status","workflowHandler","jobLabel","cancelled","resultsArray","jobPromises","Promise","all","deleteJobOnComplete","deleteMany","err","join","resultsObject","reduce","acc","cur","jobID","jobResult","jobStatus"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/queues/operations/runJobs/index.ts"],"sourcesContent":["import { v4 as uuid } from 'uuid'\n\nimport type { Job } from '../../../index.js'\nimport type { PayloadRequest, Sort, Where } from '../../../types/index.js'\nimport type { WorkflowJSON } from '../../config/types/workflowJSONTypes.js'\nimport type { WorkflowConfig, WorkflowHandler } from '../../config/types/workflowTypes.js'\nimport type { RunJobsSilent } from '../../localAPI.js'\nimport type { RunJobResult } from './runJob/index.js'\n\nimport { Forbidden } from '../../../errors/Forbidden.js'\nimport { isolateObjectProperty } from '../../../utilities/isolateObjectProperty.js'\nimport { jobsCollectionSlug } from '../../config/collection.js'\nimport { JobCancelledError, JobRunAbortedError } from '../../errors/index.js'\nimport { getCurrentDate } from '../../utilities/getCurrentDate.js'\nimport { updateJobs } from '../../utilities/updateJob.js'\nimport { startProcessingLeaseHeartbeat } from './heartbeat.js'\nimport { getUpdateJobFunction } from './runJob/getUpdateJobFunction.js'\nimport { importHandlerPath } from './runJob/importHandlerPath.js'\nimport { runJob } from './runJob/index.js'\nimport { runJSONJob } from './runJSONJob/index.js'\n\nexport type RunJobsArgs = {\n /**\n * If you want to run jobs from all queues, set this to true.\n * If you set this to true, the `queue` property will be ignored.\n *\n * @default false\n */\n allQueues?: boolean\n /**\n * ID of the job to run\n */\n id?: number | string\n /**\n * The maximum number of jobs to run in this invocation\n *\n * @default 10\n */\n limit?: number\n overrideAccess?: boolean\n /**\n * Adjust the job processing order\n *\n * FIFO would equal `createdAt` and LIFO would equal `-createdAt`.\n *\n * @default all jobs for all queues will be executed in FIFO order.\n */\n processingOrder?: Sort\n /**\n * If you want to run jobs from a specific queue, set this to the queue name.\n *\n * @default jobs from the `default` queue will be executed.\n */\n queue?: string\n req: PayloadRequest\n /**\n * By default, jobs are run in parallel.\n * If you want to run them in sequence, set this to true.\n */\n sequential?: boolean\n /**\n * If set to true, the job system will not log any output to the console (for both info and error logs).\n * Can be an option for more granular control over logging.\n *\n * This will not automatically affect user-configured logs (e.g. if you call `console.log` or `payload.logger.info` in your job code).\n *\n * @default false\n */\n silent?: RunJobsSilent\n where?: Where\n}\n\nexport type RunJobsResult = {\n jobStatus?: Record<string, RunJobResult>\n /**\n * If this is true, there for sure are no jobs remaining, regardless of the limit\n */\n noJobsRemaining?: boolean\n /**\n * Out of the jobs that were queried & processed (within the set limit), how many are remaining and retryable?\n */\n remainingJobsFromQueried: number\n}\n\nexport const runJobs = async (args: RunJobsArgs): Promise<RunJobsResult> => {\n const {\n id,\n allQueues = false,\n limit = 10,\n overrideAccess,\n processingOrder,\n queue = 'default',\n req,\n req: {\n payload,\n payload: {\n config: { jobs: jobsConfig },\n },\n },\n sequential,\n silent = false,\n where: whereFromProps,\n } = args\n\n if (!overrideAccess) {\n /**\n * By default, jobsConfig.access.run will be `defaultAccess` which is a function that returns `true` if the user is logged in.\n */\n const accessFn = jobsConfig?.access?.run ?? (() => true)\n const hasAccess = await accessFn({ req })\n if (!hasAccess) {\n throw new Forbidden(req.t)\n }\n }\n const now = getCurrentDate()\n const { duration: processingLeaseDuration, safetyBuffer: processingLeaseSafetyBuffer } =\n jobsConfig.processingLease\n const nowISOString = now.toISOString()\n const processingUntil = new Date(now.getTime() + processingLeaseDuration).toISOString()\n const processingToken = uuid()\n const and: Where[] = [\n {\n completedAt: {\n exists: false,\n },\n },\n {\n hasError: {\n not_equals: true,\n },\n },\n {\n or: [\n { processingUntil: { exists: false } },\n { processingUntil: { less_than_equal: nowISOString } },\n ],\n },\n {\n or: [\n {\n waitUntil: {\n exists: false,\n },\n },\n {\n waitUntil: {\n less_than: nowISOString,\n },\n },\n ],\n },\n ]\n\n if (!id && allQueues !== true) {\n and.push({\n queue: {\n equals: queue ?? 'default',\n },\n })\n }\n\n if (whereFromProps) {\n and.push(whereFromProps)\n }\n\n if (id) {\n and.push({ id: { equals: id } })\n }\n\n if (jobsConfig.hasConcurrency) {\n // Find currently running jobs with concurrency keys to enforce exclusive concurrency.\n // Jobs with the same concurrencyKey should not run in parallel.\n const runningJobsWithConcurrency = await payload.db.find({\n collection: jobsCollectionSlug,\n limit: 0,\n pagination: false,\n req: { transactionID: undefined },\n select: {\n concurrencyKey: true,\n },\n where: {\n and: [\n { processingUntil: { greater_than: nowISOString } },\n { concurrencyKey: { exists: true } },\n ],\n },\n })\n\n const runningConcurrencyKeys = new Set<string>()\n if (runningJobsWithConcurrency?.docs) {\n for (const doc of runningJobsWithConcurrency.docs) {\n const concurrencyKey = (doc as Job).concurrencyKey\n if (concurrencyKey) {\n runningConcurrencyKeys.add(concurrencyKey)\n }\n }\n }\n\n // Exclude jobs whose concurrencyKey is already running\n if (runningConcurrencyKeys.size > 0) {\n and.push({\n or: [\n // Jobs without a concurrency key can always run\n { concurrencyKey: { exists: false } },\n // Jobs with a concurrency key that is not currently running can run\n { concurrencyKey: { not_in: [...runningConcurrencyKeys] } },\n ],\n })\n }\n }\n\n // Claim jobs before running them so another worker cannot pick up the same jobs.\n // `processingToken` identifies which jobs were claimed by this runner.\n let jobs: Job[] = []\n\n if (id) {\n const updatedDocs = await updateJobs({\n data: {\n processingToken,\n processingUntil,\n },\n limit: 1,\n req,\n returning: true,\n where: { and },\n })\n if (updatedDocs) {\n jobs = updatedDocs\n }\n } else {\n let defaultProcessingOrder: Sort =\n payload.collections[jobsCollectionSlug]?.config.defaultSort ?? 'createdAt'\n\n const processingOrderConfig = jobsConfig.processingOrder\n if (typeof processingOrderConfig === 'function') {\n defaultProcessingOrder = await processingOrderConfig(args)\n } else if (typeof processingOrderConfig === 'object' && !Array.isArray(processingOrderConfig)) {\n if (\n !allQueues &&\n queue &&\n processingOrderConfig.queues &&\n processingOrderConfig.queues[queue]\n ) {\n defaultProcessingOrder = processingOrderConfig.queues[queue]\n } else if (processingOrderConfig.default) {\n defaultProcessingOrder = processingOrderConfig.default\n }\n } else if (typeof processingOrderConfig === 'string') {\n defaultProcessingOrder = processingOrderConfig\n }\n const updatedDocs = await updateJobs({\n data: {\n processingToken,\n processingUntil,\n },\n limit,\n req,\n returning: true,\n sort: processingOrder ?? defaultProcessingOrder,\n where: { and },\n })\n\n if (updatedDocs) {\n jobs = updatedDocs\n }\n }\n\n if (!jobs.length) {\n return {\n noJobsRemaining: true,\n remainingJobsFromQueried: 0,\n }\n }\n\n if (jobsConfig.hasConcurrency) {\n // Handle the case where multiple jobs with the same concurrencyKey were picked up in the same batch.\n // We should only run one job per concurrencyKey, releasing the others back to pending.\n const seenConcurrencyKeys = new Set<string>()\n const jobsToRun: Job[] = []\n const jobsToRelease: Job[] = []\n\n for (const job of jobs) {\n if (job.concurrencyKey) {\n if (seenConcurrencyKeys.has(job.concurrencyKey)) {\n // This job has the same concurrencyKey as another job we're already running\n jobsToRelease.push(job)\n } else {\n seenConcurrencyKeys.add(job.concurrencyKey)\n jobsToRun.push(job)\n }\n } else {\n jobsToRun.push(job)\n }\n }\n\n // Release duplicate concurrencyKey jobs back to pending state\n if (jobsToRelease.length > 0) {\n const releaseIds = jobsToRelease.map((job) => job.id)\n await updateJobs({\n data: { processingUntil: null },\n req,\n returning: false,\n where: {\n and: [\n { id: { in: releaseIds } },\n { processingToken: { equals: processingToken } },\n {\n processingUntil: {\n greater_than: new Date(\n getCurrentDate().getTime() + processingLeaseSafetyBuffer,\n ).toISOString(),\n },\n },\n ],\n },\n })\n }\n\n // Use only the filtered jobs going forward\n jobs = jobsToRun\n\n if (!jobs.length) {\n return {\n noJobsRemaining: false,\n remainingJobsFromQueried: 0,\n }\n }\n }\n\n if (!silent || (typeof silent === 'object' && !silent.info)) {\n let newCount = 0\n let retryCount = 0\n\n for (const job of jobs) {\n if (job.totalTried > 0) {\n retryCount++\n } else {\n newCount++\n }\n }\n\n payload.logger.info({\n msg: `Running ${jobs.length} jobs.`,\n new: newCount,\n retrying: retryCount,\n })\n }\n\n const successfullyCompletedJobs: (number | string)[] = []\n\n const runSingleJob = async (\n job: Job,\n ): Promise<{\n id: number | string\n result: RunJobResult\n } | null> => {\n if (!job.workflowSlug && !job.taskSlug) {\n throw new Error('Job must have either a workflowSlug or a taskSlug')\n }\n const jobReq = isolateObjectProperty(req, 'transactionID')\n\n let workflowConfig: undefined | WorkflowConfig = undefined\n\n if (job.workflowSlug && jobsConfig.workflows?.length) {\n workflowConfig = jobsConfig.workflows.find(({ slug }) => slug === job.workflowSlug)\n } else if (job.taskSlug && jobsConfig.tasks?.length) {\n const taskExists = jobsConfig.tasks.some(({ slug }) => slug === job.taskSlug)\n if (taskExists) {\n workflowConfig = {\n slug: 'singleTask',\n handler: async ({ job, tasks }) => {\n await tasks[job.taskSlug as string]!('1', {\n input: job.input,\n })\n },\n }\n }\n }\n\n try {\n if (!workflowConfig) {\n // Permanently fail jobs whose task/workflow slug is no longer registered in config — they can never complete.\n const errorMessage = `${job.taskSlug ? `Task '${job.taskSlug}'` : `Workflow '${job.workflowSlug}'`} is not registered in payload.config.jobs.`\n\n if (!silent || (typeof silent === 'object' && !silent.error)) {\n payload.logger.error({\n msg: `Error running job ${job.workflowSlug || `Task: ${job.taskSlug}`} id: ${job.id} - ${errorMessage}`,\n })\n }\n\n const updateJob = getUpdateJobFunction(job, jobReq)\n await updateJob({\n error: { message: errorMessage },\n hasError: true,\n processingUntil: null,\n totalTried: (job.totalTried ?? 0) + 1,\n })\n\n return {\n id: job.id,\n result: {\n status: 'error-reached-max-retries',\n },\n }\n }\n\n const updateJob = getUpdateJobFunction(job, jobReq)\n\n // the runner will either be passed to the config\n // OR it will be a path, which we will need to import via eval to avoid\n // Next.js compiler dynamic import expression errors\n let workflowHandler: WorkflowHandler | WorkflowJSON\n if (\n typeof workflowConfig.handler === 'function' ||\n (typeof workflowConfig.handler === 'object' && Array.isArray(workflowConfig.handler))\n ) {\n workflowHandler = workflowConfig.handler\n } else {\n workflowHandler = await importHandlerPath<typeof workflowHandler>(workflowConfig.handler)\n\n if (!workflowHandler) {\n const jobLabel = job.workflowSlug || `Task: ${job.taskSlug}`\n const errorMessage = `Can't find runner while importing with the path ${workflowConfig.handler} in job type ${jobLabel}.`\n if (!silent || (typeof silent === 'object' && !silent.error)) {\n payload.logger.error(errorMessage)\n }\n\n await updateJob({\n error: {\n error: errorMessage,\n },\n hasError: true,\n processingUntil: null,\n })\n\n return {\n id: job.id,\n result: {\n status: 'error-reached-max-retries',\n },\n }\n }\n }\n\n if (typeof workflowHandler === 'function') {\n const result = await runJob({\n job,\n req: jobReq,\n silent,\n updateJob,\n workflowConfig,\n workflowHandler,\n })\n\n if (result.status === 'success') {\n successfullyCompletedJobs.push(job.id)\n }\n\n return { id: job.id, result }\n } else {\n const result = await runJSONJob({\n job,\n req: jobReq,\n silent,\n updateJob,\n workflowConfig,\n workflowHandler,\n })\n\n if (result.status === 'success') {\n successfullyCompletedJobs.push(job.id)\n }\n\n return { id: job.id, result }\n }\n } catch (error) {\n if (error instanceof JobRunAbortedError) {\n return null\n }\n if (error instanceof JobCancelledError) {\n if (\n !(job.error as Record<string, unknown> | undefined)?.cancelled ||\n !job.hasError ||\n job.processingUntil ||\n job.completedAt ||\n job.waitUntil\n ) {\n // When using the local API to cancel jobs, the local API will update the job data for us to ensure the job is cancelled.\n // But when throwing a JobCancelledError within a task or workflow handler, we are responsible for updating the job data ourselves.\n // Use the lease-protected getUpdateJobFunction so an old worker cannot cancel the job after another worker claims it.\n const updateJob = getUpdateJobFunction(job, jobReq)\n await updateJob({\n completedAt: null,\n error: {\n cancelled: true,\n message: error.message,\n },\n hasError: true,\n processingUntil: null,\n waitUntil: null,\n })\n }\n\n return {\n id: job.id,\n result: {\n status: 'error-reached-max-retries',\n },\n }\n }\n throw error\n }\n }\n\n const stopHeartbeat = startProcessingLeaseHeartbeat({\n jobIDs: jobs.map((job) => job.id),\n processingLeaseDuration,\n processingLeaseSafetyBuffer,\n processingToken,\n req,\n silent,\n })\n\n let resultsArray: { id: number | string; result: RunJobResult }[] = []\n try {\n if (sequential) {\n for (const job of jobs) {\n const result = await runSingleJob(job)\n if (result) {\n resultsArray.push(result)\n }\n }\n } else {\n const jobPromises = jobs.map(runSingleJob)\n resultsArray = (await Promise.all(jobPromises)).filter((result) => result !== null)\n }\n } finally {\n stopHeartbeat()\n }\n\n if (jobsConfig.deleteJobOnComplete && successfullyCompletedJobs.length) {\n try {\n await payload.db.deleteMany({\n collection: jobsCollectionSlug,\n where: { id: { in: successfullyCompletedJobs } },\n })\n } catch (err) {\n if (!silent || (typeof silent === 'object' && !silent.error)) {\n payload.logger.error({\n err,\n msg: `Failed to delete jobs ${successfullyCompletedJobs.join(', ')} on complete`,\n })\n }\n }\n }\n\n const resultsObject: RunJobsResult['jobStatus'] = resultsArray.reduce(\n (acc, cur) => {\n if (cur !== null) {\n // Check if there's a valid result to include\n acc[cur.id] = cur.result\n }\n return acc\n },\n {} as Record<string, RunJobResult>,\n )\n\n let remainingJobsFromQueried = 0\n for (const jobID in resultsObject) {\n const jobResult = resultsObject[jobID]\n if (jobResult?.status === 'error') {\n remainingJobsFromQueried++ // Can be retried\n }\n }\n\n return {\n jobStatus: resultsObject,\n remainingJobsFromQueried,\n }\n}\n"],"names":["v4","uuid","Forbidden","isolateObjectProperty","jobsCollectionSlug","JobCancelledError","JobRunAbortedError","getCurrentDate","updateJobs","startProcessingLeaseHeartbeat","getUpdateJobFunction","importHandlerPath","runJob","runJSONJob","runJobs","args","id","allQueues","limit","overrideAccess","processingOrder","queue","req","payload","config","jobs","jobsConfig","sequential","silent","where","whereFromProps","accessFn","access","run","hasAccess","t","now","duration","processingLeaseDuration","safetyBuffer","processingLeaseSafetyBuffer","processingLease","nowISOString","toISOString","processingUntil","Date","getTime","processingToken","and","completedAt","exists","hasError","not_equals","or","less_than_equal","waitUntil","less_than","push","equals","hasConcurrency","runningJobsWithConcurrency","db","find","collection","pagination","transactionID","undefined","select","concurrencyKey","greater_than","runningConcurrencyKeys","Set","docs","doc","add","size","not_in","updatedDocs","data","returning","defaultProcessingOrder","collections","defaultSort","processingOrderConfig","Array","isArray","queues","default","sort","length","noJobsRemaining","remainingJobsFromQueried","seenConcurrencyKeys","jobsToRun","jobsToRelease","job","has","releaseIds","map","in","info","newCount","retryCount","totalTried","logger","msg","new","retrying","successfullyCompletedJobs","runSingleJob","workflowSlug","taskSlug","Error","jobReq","workflowConfig","workflows","slug","tasks","taskExists","some","handler","input","errorMessage","error","updateJob","message","result","status","workflowHandler","jobLabel","cancelled","stopHeartbeat","jobIDs","resultsArray","jobPromises","Promise","all","filter","deleteJobOnComplete","deleteMany","err","join","resultsObject","reduce","acc","cur","jobID","jobResult","jobStatus"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/queues/operations/runJobs/runJSONJob/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,4CAA4C,CAAA;AAC5F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAA;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAOtD,KAAK,IAAI,GAAG;IACV,GAAG,EAAE,GAAG,CAAA;IACR,GAAG,EAAE,cAAc,CAAA;IACnB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,SAAS,EAAE,iBAAiB,CAAA;IAC5B,cAAc,EAAE,cAAc,CAAA;IAC9B,eAAe,EAAE,YAAY,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,YAAY,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,UAAU,sEAOpB,IAAI,KAAG,OAAO,CAAC,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/queues/operations/runJobs/runJSONJob/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,4CAA4C,CAAA;AAC5F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAA;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAOtD,KAAK,IAAI,GAAG;IACV,GAAG,EAAE,GAAG,CAAA;IACR,GAAG,EAAE,cAAc,CAAA;IACnB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,SAAS,EAAE,iBAAiB,CAAA;IAC5B,cAAc,EAAE,cAAc,CAAA;IAC9B,eAAe,EAAE,YAAY,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,YAAY,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,UAAU,sEAOpB,IAAI,KAAG,OAAO,CAAC,gBAAgB,CA4GjC,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { handleWorkflowError } from '../../../errors/handleWorkflowError.js';
|
|
2
|
-
import { WorkflowError } from '../../../errors/index.js';
|
|
2
|
+
import { JobCancelledError, JobRunAbortedError, WorkflowError } from '../../../errors/index.js';
|
|
3
3
|
import { getCurrentDate } from '../../../utilities/getCurrentDate.js';
|
|
4
4
|
import { getRunTaskFunction } from '../runJob/getRunTaskFunction.js';
|
|
5
5
|
export const runJSONJob = async ({ job, req, silent = false, updateJob, workflowConfig, workflowHandler })=>{
|
|
@@ -41,6 +41,9 @@ export const runJSONJob = async ({ job, req, silent = false, updateJob, workflow
|
|
|
41
41
|
}
|
|
42
42
|
}));
|
|
43
43
|
} catch (error) {
|
|
44
|
+
if (error instanceof JobCancelledError || error instanceof JobRunAbortedError) {
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
44
47
|
const { hasFinalError } = await handleWorkflowError({
|
|
45
48
|
error: error instanceof WorkflowError ? error : new WorkflowError({
|
|
46
49
|
job,
|
|
@@ -77,14 +80,14 @@ export const runJSONJob = async ({ job, req, silent = false, updateJob, workflow
|
|
|
77
80
|
if (workflowCompleted) {
|
|
78
81
|
await updateJob({
|
|
79
82
|
completedAt: getCurrentDate().toISOString(),
|
|
80
|
-
|
|
83
|
+
processingUntil: null,
|
|
81
84
|
totalTried: (job.totalTried ?? 0) + 1
|
|
82
85
|
});
|
|
83
86
|
return {
|
|
84
87
|
status: 'success'
|
|
85
88
|
};
|
|
86
89
|
} else {
|
|
87
|
-
// Retry the job - no need to bump
|
|
90
|
+
// Retry the job - no need to bump processingUntil or totalTried as this does not count as a retry. A condition of a different task might have just opened up!
|
|
88
91
|
return await runJSONJob({
|
|
89
92
|
job,
|
|
90
93
|
req,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/queues/operations/runJobs/runJSONJob/index.ts"],"sourcesContent":["import type { Job } from '../../../../index.js'\nimport type { PayloadRequest } from '../../../../types/index.js'\nimport type { WorkflowJSON, WorkflowStep } from '../../../config/types/workflowJSONTypes.js'\nimport type { WorkflowConfig } from '../../../config/types/workflowTypes.js'\nimport type { RunJobsSilent } from '../../../localAPI.js'\nimport type { UpdateJobFunction } from '../runJob/getUpdateJobFunction.js'\nimport type { JobRunStatus } from '../runJob/index.js'\n\nimport { handleWorkflowError } from '../../../errors/handleWorkflowError.js'\nimport { WorkflowError } from '../../../errors/index.js'\nimport { getCurrentDate } from '../../../utilities/getCurrentDate.js'\nimport { getRunTaskFunction } from '../runJob/getRunTaskFunction.js'\n\ntype Args = {\n job: Job\n req: PayloadRequest\n /**\n * If set to true, the job system will not log any output to the console (for both info and error logs).\n * Can be an option for more granular control over logging.\n *\n * This will not automatically affect user-configured logs (e.g. if you call `console.log` or `payload.logger.info` in your job code).\n *\n * @default false\n */\n silent?: RunJobsSilent\n updateJob: UpdateJobFunction\n workflowConfig: WorkflowConfig\n workflowHandler: WorkflowJSON\n}\n\nexport type RunJSONJobResult = {\n status: JobRunStatus\n}\n\nexport const runJSONJob = async ({\n job,\n req,\n silent = false,\n updateJob,\n workflowConfig,\n workflowHandler,\n}: Args): Promise<RunJSONJobResult> => {\n const stepsToRun: WorkflowStep<string>[] = []\n\n for (const step of workflowHandler) {\n if ('task' in step) {\n if (job?.taskStatus?.[step.task]?.[step.id]?.complete) {\n continue\n }\n } else {\n if (job?.taskStatus?.['inline']?.[step.id]?.complete) {\n continue\n }\n }\n if (step.condition && !step.condition({ job })) {\n continue\n }\n stepsToRun.push(step)\n }\n\n const tasks = getRunTaskFunction(job, workflowConfig, req, false, updateJob)\n const inlineTask = getRunTaskFunction(job, workflowConfig, req, true, updateJob)\n\n // Run the job\n try {\n await Promise.all(\n stepsToRun.map(async (step) => {\n if ('task' in step) {\n await tasks[step.task]!(step.id, {\n input: step.input ? step.input({ job }) : {},\n retries: step.retries,\n })\n } else {\n await inlineTask(step.id, {\n retries: step.retries,\n task: step.inlineTask
|
|
1
|
+
{"version":3,"sources":["../../../../../src/queues/operations/runJobs/runJSONJob/index.ts"],"sourcesContent":["import type { Job } from '../../../../index.js'\nimport type { PayloadRequest } from '../../../../types/index.js'\nimport type { WorkflowJSON, WorkflowStep } from '../../../config/types/workflowJSONTypes.js'\nimport type { WorkflowConfig } from '../../../config/types/workflowTypes.js'\nimport type { RunJobsSilent } from '../../../localAPI.js'\nimport type { UpdateJobFunction } from '../runJob/getUpdateJobFunction.js'\nimport type { JobRunStatus } from '../runJob/index.js'\n\nimport { handleWorkflowError } from '../../../errors/handleWorkflowError.js'\nimport { JobCancelledError, JobRunAbortedError, WorkflowError } from '../../../errors/index.js'\nimport { getCurrentDate } from '../../../utilities/getCurrentDate.js'\nimport { getRunTaskFunction } from '../runJob/getRunTaskFunction.js'\n\ntype Args = {\n job: Job\n req: PayloadRequest\n /**\n * If set to true, the job system will not log any output to the console (for both info and error logs).\n * Can be an option for more granular control over logging.\n *\n * This will not automatically affect user-configured logs (e.g. if you call `console.log` or `payload.logger.info` in your job code).\n *\n * @default false\n */\n silent?: RunJobsSilent\n updateJob: UpdateJobFunction\n workflowConfig: WorkflowConfig\n workflowHandler: WorkflowJSON\n}\n\nexport type RunJSONJobResult = {\n status: JobRunStatus\n}\n\nexport const runJSONJob = async ({\n job,\n req,\n silent = false,\n updateJob,\n workflowConfig,\n workflowHandler,\n}: Args): Promise<RunJSONJobResult> => {\n const stepsToRun: WorkflowStep<string>[] = []\n\n for (const step of workflowHandler) {\n if ('task' in step) {\n if (job?.taskStatus?.[step.task]?.[step.id]?.complete) {\n continue\n }\n } else {\n if (job?.taskStatus?.['inline']?.[step.id]?.complete) {\n continue\n }\n }\n if (step.condition && !step.condition({ job })) {\n continue\n }\n stepsToRun.push(step)\n }\n\n const tasks = getRunTaskFunction(job, workflowConfig, req, false, updateJob)\n const inlineTask = getRunTaskFunction(job, workflowConfig, req, true, updateJob)\n\n // Run the job\n try {\n await Promise.all(\n stepsToRun.map(async (step) => {\n if ('task' in step) {\n await tasks[step.task]!(step.id, {\n input: step.input ? step.input({ job }) : {},\n retries: step.retries,\n })\n } else {\n await inlineTask(step.id, {\n retries: step.retries,\n task: step.inlineTask,\n })\n }\n }),\n )\n } catch (error) {\n if (error instanceof JobCancelledError || error instanceof JobRunAbortedError) {\n throw error\n }\n\n const { hasFinalError } = await handleWorkflowError({\n error:\n error instanceof WorkflowError\n ? error\n : new WorkflowError({\n job,\n message:\n typeof error === 'object' && error && 'message' in error\n ? (error.message as string)\n : 'An unhandled error occurred',\n workflowConfig,\n }),\n silent,\n\n req,\n updateJob,\n })\n\n return {\n status: hasFinalError ? 'error-reached-max-retries' : 'error',\n }\n }\n\n // Check if workflow has completed\n let workflowCompleted = false\n for (const [slug, map] of Object.entries(job.taskStatus)) {\n for (const [id, taskStatus] of Object.entries(map)) {\n if (taskStatus.complete) {\n const step = workflowHandler.find((step) => {\n if ('task' in step) {\n return step.task === slug && step.id === id\n } else {\n return step.id === id && slug === 'inline'\n }\n })\n if (step?.completesJob) {\n workflowCompleted = true\n break\n }\n }\n }\n }\n\n if (workflowCompleted) {\n await updateJob({\n completedAt: getCurrentDate().toISOString(),\n processingUntil: null,\n totalTried: (job.totalTried ?? 0) + 1,\n })\n\n return {\n status: 'success',\n }\n } else {\n // Retry the job - no need to bump processingUntil or totalTried as this does not count as a retry. A condition of a different task might have just opened up!\n return await runJSONJob({\n job,\n req,\n silent,\n updateJob,\n workflowConfig,\n workflowHandler,\n })\n }\n}\n"],"names":["handleWorkflowError","JobCancelledError","JobRunAbortedError","WorkflowError","getCurrentDate","getRunTaskFunction","runJSONJob","job","req","silent","updateJob","workflowConfig","workflowHandler","stepsToRun","step","taskStatus","task","id","complete","condition","push","tasks","inlineTask","Promise","all","map","input","retries","error","hasFinalError","message","status","workflowCompleted","slug","Object","entries","find","completesJob","completedAt","toISOString","processingUntil","totalTried"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ObjectIdImport from 'bson-objectid';
|
|
2
|
-
import { JobCancelledError, TaskError } from '../../../errors/index.js';
|
|
2
|
+
import { JobCancelledError, JobRunAbortedError, TaskError } from '../../../errors/index.js';
|
|
3
3
|
import { getCurrentDate } from '../../../utilities/getCurrentDate.js';
|
|
4
4
|
import { getTaskHandlerFromConfig } from './importHandlerPath.js';
|
|
5
5
|
const ObjectId = 'default' in ObjectIdImport ? ObjectIdImport.default : ObjectIdImport;
|
|
@@ -75,8 +75,8 @@ export const getRunTaskFunction = (job, workflowConfig, req, isInline, updateJob
|
|
|
75
75
|
})
|
|
76
76
|
}))?.output;
|
|
77
77
|
} catch (err) {
|
|
78
|
-
if (err instanceof JobCancelledError) {
|
|
79
|
-
//
|
|
78
|
+
if (err instanceof JobCancelledError || err instanceof JobRunAbortedError) {
|
|
79
|
+
// Job run aborts are handled by the top-level runner.
|
|
80
80
|
throw err;
|
|
81
81
|
}
|
|
82
82
|
throw new TaskError({
|
|
@@ -106,9 +106,9 @@ export const getRunTaskFunction = (job, workflowConfig, req, isInline, updateJob
|
|
|
106
106
|
id: new ObjectId().toHexString(),
|
|
107
107
|
completedAt: getCurrentDate().toISOString(),
|
|
108
108
|
executedAt: executedAt.toISOString(),
|
|
109
|
-
input,
|
|
109
|
+
input: input ?? {},
|
|
110
110
|
output,
|
|
111
|
-
parent
|
|
111
|
+
parent,
|
|
112
112
|
state: 'succeeded',
|
|
113
113
|
taskID,
|
|
114
114
|
taskSlug
|