@nicnocquee/dataqueue 1.16.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.cjs +51 -3
- package/dist/index.cjs +44 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -31
- package/dist/index.d.ts +32 -31
- package/dist/index.js +44 -42
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/src/index.test.ts +30 -30
- package/src/index.ts +1 -1
- package/src/processor.test.ts +24 -24
- package/src/processor.ts +5 -5
- package/src/queue.test.ts +74 -73
- package/src/queue.ts +43 -40
- package/src/types.ts +37 -30
- package/src/utils.ts +19 -0
package/dist/index.d.cts
CHANGED
|
@@ -2,11 +2,11 @@ import { Pool } from 'pg';
|
|
|
2
2
|
|
|
3
3
|
type JobType<PayloadMap> = keyof PayloadMap & string;
|
|
4
4
|
interface JobOptions<PayloadMap, T extends JobType<PayloadMap>> {
|
|
5
|
-
|
|
5
|
+
jobType: T;
|
|
6
6
|
payload: PayloadMap[T];
|
|
7
|
-
|
|
7
|
+
maxAttempts?: number;
|
|
8
8
|
priority?: number;
|
|
9
|
-
|
|
9
|
+
runAt?: Date | null;
|
|
10
10
|
/**
|
|
11
11
|
* Timeout for this job in milliseconds. If not set, uses the processor default or unlimited.
|
|
12
12
|
*/
|
|
@@ -22,9 +22,9 @@ declare enum JobEventType {
|
|
|
22
22
|
}
|
|
23
23
|
interface JobEvent {
|
|
24
24
|
id: number;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
jobId: number;
|
|
26
|
+
eventType: JobEventType;
|
|
27
|
+
createdAt: Date;
|
|
28
28
|
metadata: any;
|
|
29
29
|
}
|
|
30
30
|
declare enum FailureReason {
|
|
@@ -32,53 +32,54 @@ declare enum FailureReason {
|
|
|
32
32
|
HandlerError = "handler_error",
|
|
33
33
|
NoHandler = "no_handler"
|
|
34
34
|
}
|
|
35
|
+
type JobStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled';
|
|
35
36
|
interface JobRecord<PayloadMap, T extends JobType<PayloadMap>> {
|
|
36
37
|
id: number;
|
|
37
|
-
|
|
38
|
+
jobType: T;
|
|
38
39
|
payload: PayloadMap[T];
|
|
39
|
-
status:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
status: JobStatus;
|
|
41
|
+
createdAt: Date;
|
|
42
|
+
updatedAt: Date;
|
|
43
|
+
lockedAt: Date | null;
|
|
44
|
+
lockedBy: string | null;
|
|
44
45
|
attempts: number;
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
maxAttempts: number;
|
|
47
|
+
nextAttemptAt: Date | null;
|
|
47
48
|
priority: number;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
runAt: Date;
|
|
50
|
+
pendingReason?: string | null;
|
|
51
|
+
errorHistory?: {
|
|
51
52
|
message: string;
|
|
52
53
|
timestamp: string;
|
|
53
54
|
}[];
|
|
54
55
|
/**
|
|
55
56
|
* Timeout for this job in milliseconds (null means no timeout).
|
|
56
57
|
*/
|
|
57
|
-
|
|
58
|
+
timeoutMs?: number | null;
|
|
58
59
|
/**
|
|
59
60
|
* The reason for the last failure, if any.
|
|
60
61
|
*/
|
|
61
|
-
|
|
62
|
+
failureReason?: FailureReason | null;
|
|
62
63
|
/**
|
|
63
64
|
* The time the job was completed, if completed.
|
|
64
65
|
*/
|
|
65
|
-
|
|
66
|
+
completedAt: Date | null;
|
|
66
67
|
/**
|
|
67
68
|
* The time the job was first picked up for processing.
|
|
68
69
|
*/
|
|
69
|
-
|
|
70
|
+
startedAt: Date | null;
|
|
70
71
|
/**
|
|
71
72
|
* The time the job was last retried.
|
|
72
73
|
*/
|
|
73
|
-
|
|
74
|
+
lastRetriedAt: Date | null;
|
|
74
75
|
/**
|
|
75
76
|
* The time the job last failed.
|
|
76
77
|
*/
|
|
77
|
-
|
|
78
|
+
lastFailedAt: Date | null;
|
|
78
79
|
/**
|
|
79
80
|
* The time the job was last cancelled.
|
|
80
81
|
*/
|
|
81
|
-
|
|
82
|
+
lastCancelledAt: Date | null;
|
|
82
83
|
}
|
|
83
84
|
type JobHandler<PayloadMap, T extends keyof PayloadMap> = (payload: PayloadMap[T], signal: AbortSignal) => Promise<void>;
|
|
84
85
|
type JobHandlers<PayloadMap> = {
|
|
@@ -163,9 +164,9 @@ interface JobQueue<PayloadMap> {
|
|
|
163
164
|
* Get jobs by their status, with pagination.
|
|
164
165
|
* - If no limit is provided, all jobs are returned.
|
|
165
166
|
* - If no offset is provided, the first page is returned.
|
|
166
|
-
* - The jobs are returned in descending order of
|
|
167
|
+
* - The jobs are returned in descending order of createdAt.
|
|
167
168
|
*/
|
|
168
|
-
getJobsByStatus: <T extends JobType<PayloadMap>>(status:
|
|
169
|
+
getJobsByStatus: <T extends JobType<PayloadMap>>(status: JobStatus, limit?: number, offset?: number) => Promise<JobRecord<PayloadMap, T>[]>;
|
|
169
170
|
/**
|
|
170
171
|
* Get all jobs.
|
|
171
172
|
*/
|
|
@@ -196,14 +197,14 @@ interface JobQueue<PayloadMap> {
|
|
|
196
197
|
* - If no filters are provided, all upcoming jobs are cancelled.
|
|
197
198
|
* - If filters are provided, only jobs that match the filters are cancelled.
|
|
198
199
|
* - The filters are:
|
|
199
|
-
* -
|
|
200
|
+
* - jobType: The job type to cancel.
|
|
200
201
|
* - priority: The priority of the job to cancel.
|
|
201
|
-
* -
|
|
202
|
+
* - runAt: The time the job is scheduled to run at.
|
|
202
203
|
*/
|
|
203
204
|
cancelAllUpcomingJobs: (filters?: {
|
|
204
|
-
|
|
205
|
+
jobType?: string;
|
|
205
206
|
priority?: number;
|
|
206
|
-
|
|
207
|
+
runAt?: Date;
|
|
207
208
|
}) => Promise<number>;
|
|
208
209
|
/**
|
|
209
210
|
* Create a job processor. Handlers must be provided per-processor.
|
|
@@ -224,4 +225,4 @@ interface JobQueue<PayloadMap> {
|
|
|
224
225
|
*/
|
|
225
226
|
declare const initJobQueue: <PayloadMap = any>(config: JobQueueConfig) => Promise<JobQueue<PayloadMap>>;
|
|
226
227
|
|
|
227
|
-
export { FailureReason, type JobEvent, JobEventType, type JobHandler, type JobHandlers, type JobOptions, type JobQueue, type JobQueueConfig, type JobRecord, type JobType, type Processor, type ProcessorOptions, initJobQueue };
|
|
228
|
+
export { FailureReason, type JobEvent, JobEventType, type JobHandler, type JobHandlers, type JobOptions, type JobQueue, type JobQueueConfig, type JobRecord, type JobStatus, type JobType, type Processor, type ProcessorOptions, initJobQueue };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { Pool } from 'pg';
|
|
|
2
2
|
|
|
3
3
|
type JobType<PayloadMap> = keyof PayloadMap & string;
|
|
4
4
|
interface JobOptions<PayloadMap, T extends JobType<PayloadMap>> {
|
|
5
|
-
|
|
5
|
+
jobType: T;
|
|
6
6
|
payload: PayloadMap[T];
|
|
7
|
-
|
|
7
|
+
maxAttempts?: number;
|
|
8
8
|
priority?: number;
|
|
9
|
-
|
|
9
|
+
runAt?: Date | null;
|
|
10
10
|
/**
|
|
11
11
|
* Timeout for this job in milliseconds. If not set, uses the processor default or unlimited.
|
|
12
12
|
*/
|
|
@@ -22,9 +22,9 @@ declare enum JobEventType {
|
|
|
22
22
|
}
|
|
23
23
|
interface JobEvent {
|
|
24
24
|
id: number;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
jobId: number;
|
|
26
|
+
eventType: JobEventType;
|
|
27
|
+
createdAt: Date;
|
|
28
28
|
metadata: any;
|
|
29
29
|
}
|
|
30
30
|
declare enum FailureReason {
|
|
@@ -32,53 +32,54 @@ declare enum FailureReason {
|
|
|
32
32
|
HandlerError = "handler_error",
|
|
33
33
|
NoHandler = "no_handler"
|
|
34
34
|
}
|
|
35
|
+
type JobStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled';
|
|
35
36
|
interface JobRecord<PayloadMap, T extends JobType<PayloadMap>> {
|
|
36
37
|
id: number;
|
|
37
|
-
|
|
38
|
+
jobType: T;
|
|
38
39
|
payload: PayloadMap[T];
|
|
39
|
-
status:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
status: JobStatus;
|
|
41
|
+
createdAt: Date;
|
|
42
|
+
updatedAt: Date;
|
|
43
|
+
lockedAt: Date | null;
|
|
44
|
+
lockedBy: string | null;
|
|
44
45
|
attempts: number;
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
maxAttempts: number;
|
|
47
|
+
nextAttemptAt: Date | null;
|
|
47
48
|
priority: number;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
runAt: Date;
|
|
50
|
+
pendingReason?: string | null;
|
|
51
|
+
errorHistory?: {
|
|
51
52
|
message: string;
|
|
52
53
|
timestamp: string;
|
|
53
54
|
}[];
|
|
54
55
|
/**
|
|
55
56
|
* Timeout for this job in milliseconds (null means no timeout).
|
|
56
57
|
*/
|
|
57
|
-
|
|
58
|
+
timeoutMs?: number | null;
|
|
58
59
|
/**
|
|
59
60
|
* The reason for the last failure, if any.
|
|
60
61
|
*/
|
|
61
|
-
|
|
62
|
+
failureReason?: FailureReason | null;
|
|
62
63
|
/**
|
|
63
64
|
* The time the job was completed, if completed.
|
|
64
65
|
*/
|
|
65
|
-
|
|
66
|
+
completedAt: Date | null;
|
|
66
67
|
/**
|
|
67
68
|
* The time the job was first picked up for processing.
|
|
68
69
|
*/
|
|
69
|
-
|
|
70
|
+
startedAt: Date | null;
|
|
70
71
|
/**
|
|
71
72
|
* The time the job was last retried.
|
|
72
73
|
*/
|
|
73
|
-
|
|
74
|
+
lastRetriedAt: Date | null;
|
|
74
75
|
/**
|
|
75
76
|
* The time the job last failed.
|
|
76
77
|
*/
|
|
77
|
-
|
|
78
|
+
lastFailedAt: Date | null;
|
|
78
79
|
/**
|
|
79
80
|
* The time the job was last cancelled.
|
|
80
81
|
*/
|
|
81
|
-
|
|
82
|
+
lastCancelledAt: Date | null;
|
|
82
83
|
}
|
|
83
84
|
type JobHandler<PayloadMap, T extends keyof PayloadMap> = (payload: PayloadMap[T], signal: AbortSignal) => Promise<void>;
|
|
84
85
|
type JobHandlers<PayloadMap> = {
|
|
@@ -163,9 +164,9 @@ interface JobQueue<PayloadMap> {
|
|
|
163
164
|
* Get jobs by their status, with pagination.
|
|
164
165
|
* - If no limit is provided, all jobs are returned.
|
|
165
166
|
* - If no offset is provided, the first page is returned.
|
|
166
|
-
* - The jobs are returned in descending order of
|
|
167
|
+
* - The jobs are returned in descending order of createdAt.
|
|
167
168
|
*/
|
|
168
|
-
getJobsByStatus: <T extends JobType<PayloadMap>>(status:
|
|
169
|
+
getJobsByStatus: <T extends JobType<PayloadMap>>(status: JobStatus, limit?: number, offset?: number) => Promise<JobRecord<PayloadMap, T>[]>;
|
|
169
170
|
/**
|
|
170
171
|
* Get all jobs.
|
|
171
172
|
*/
|
|
@@ -196,14 +197,14 @@ interface JobQueue<PayloadMap> {
|
|
|
196
197
|
* - If no filters are provided, all upcoming jobs are cancelled.
|
|
197
198
|
* - If filters are provided, only jobs that match the filters are cancelled.
|
|
198
199
|
* - The filters are:
|
|
199
|
-
* -
|
|
200
|
+
* - jobType: The job type to cancel.
|
|
200
201
|
* - priority: The priority of the job to cancel.
|
|
201
|
-
* -
|
|
202
|
+
* - runAt: The time the job is scheduled to run at.
|
|
202
203
|
*/
|
|
203
204
|
cancelAllUpcomingJobs: (filters?: {
|
|
204
|
-
|
|
205
|
+
jobType?: string;
|
|
205
206
|
priority?: number;
|
|
206
|
-
|
|
207
|
+
runAt?: Date;
|
|
207
208
|
}) => Promise<number>;
|
|
208
209
|
/**
|
|
209
210
|
* Create a job processor. Handlers must be provided per-processor.
|
|
@@ -224,4 +225,4 @@ interface JobQueue<PayloadMap> {
|
|
|
224
225
|
*/
|
|
225
226
|
declare const initJobQueue: <PayloadMap = any>(config: JobQueueConfig) => Promise<JobQueue<PayloadMap>>;
|
|
226
227
|
|
|
227
|
-
export { FailureReason, type JobEvent, JobEventType, type JobHandler, type JobHandlers, type JobOptions, type JobQueue, type JobQueueConfig, type JobRecord, type JobType, type Processor, type ProcessorOptions, initJobQueue };
|
|
228
|
+
export { FailureReason, type JobEvent, JobEventType, type JobHandler, type JobHandlers, type JobOptions, type JobQueue, type JobQueueConfig, type JobRecord, type JobStatus, type JobType, type Processor, type ProcessorOptions, initJobQueue };
|
package/dist/index.js
CHANGED
|
@@ -46,26 +46,26 @@ var recordJobEvent = async (pool, jobId, eventType, metadata) => {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
var addJob = async (pool, {
|
|
49
|
-
|
|
49
|
+
jobType,
|
|
50
50
|
payload,
|
|
51
|
-
|
|
51
|
+
maxAttempts = 3,
|
|
52
52
|
priority = 0,
|
|
53
|
-
|
|
53
|
+
runAt = null,
|
|
54
54
|
timeoutMs = void 0
|
|
55
55
|
}) => {
|
|
56
56
|
const client = await pool.connect();
|
|
57
57
|
try {
|
|
58
58
|
let result;
|
|
59
|
-
if (
|
|
59
|
+
if (runAt) {
|
|
60
60
|
result = await client.query(
|
|
61
61
|
`INSERT INTO job_queue
|
|
62
62
|
(job_type, payload, max_attempts, priority, run_at, timeout_ms)
|
|
63
63
|
VALUES ($1, $2, $3, $4, $5, $6)
|
|
64
64
|
RETURNING id`,
|
|
65
|
-
[
|
|
65
|
+
[jobType, payload, maxAttempts, priority, runAt, timeoutMs ?? null]
|
|
66
66
|
);
|
|
67
67
|
log(
|
|
68
|
-
`Added job ${result.rows[0].id}: payload ${JSON.stringify(payload)},
|
|
68
|
+
`Added job ${result.rows[0].id}: payload ${JSON.stringify(payload)}, runAt ${runAt.toISOString()}, priority ${priority}, maxAttempts ${maxAttempts} jobType ${jobType}`
|
|
69
69
|
);
|
|
70
70
|
} else {
|
|
71
71
|
result = await client.query(
|
|
@@ -73,14 +73,14 @@ var addJob = async (pool, {
|
|
|
73
73
|
(job_type, payload, max_attempts, priority, timeout_ms)
|
|
74
74
|
VALUES ($1, $2, $3, $4, $5)
|
|
75
75
|
RETURNING id`,
|
|
76
|
-
[
|
|
76
|
+
[jobType, payload, maxAttempts, priority, timeoutMs ?? null]
|
|
77
77
|
);
|
|
78
78
|
log(
|
|
79
|
-
`Added job ${result.rows[0].id}: payload ${JSON.stringify(payload)}, priority ${priority},
|
|
79
|
+
`Added job ${result.rows[0].id}: payload ${JSON.stringify(payload)}, priority ${priority}, maxAttempts ${maxAttempts} jobType ${jobType}`
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
82
|
await recordJobEvent(pool, result.rows[0].id, "added" /* Added */, {
|
|
83
|
-
|
|
83
|
+
jobType,
|
|
84
84
|
payload
|
|
85
85
|
});
|
|
86
86
|
return result.rows[0].id;
|
|
@@ -94,19 +94,21 @@ var addJob = async (pool, {
|
|
|
94
94
|
var getJob = async (pool, id) => {
|
|
95
95
|
const client = await pool.connect();
|
|
96
96
|
try {
|
|
97
|
-
const result = await client.query(
|
|
98
|
-
id
|
|
99
|
-
|
|
97
|
+
const result = await client.query(
|
|
98
|
+
`SELECT id, job_type AS "jobType", payload, status, max_attempts AS "maxAttempts", attempts, priority, run_at AS "runAt", timeout_ms AS "timeoutMs", created_at AS "createdAt", updated_at AS "updatedAt", started_at AS "startedAt", completed_at AS "completedAt", last_failed_at AS "lastFailedAt", locked_at AS "lockedAt", locked_by AS "lockedBy", error_history AS "errorHistory", failure_reason AS "failureReason", next_attempt_at AS "nextAttemptAt", last_failed_at AS "lastFailedAt", last_retried_at AS "lastRetriedAt", last_cancelled_at AS "lastCancelledAt", pending_reason AS "pendingReason" FROM job_queue WHERE id = $1`,
|
|
99
|
+
[id]
|
|
100
|
+
);
|
|
100
101
|
if (result.rows.length === 0) {
|
|
101
102
|
log(`Job ${id} not found`);
|
|
102
103
|
return null;
|
|
103
104
|
}
|
|
104
105
|
log(`Found job ${id}`);
|
|
106
|
+
const job = result.rows[0];
|
|
105
107
|
return {
|
|
106
|
-
...
|
|
107
|
-
payload:
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
...job,
|
|
109
|
+
payload: job.payload,
|
|
110
|
+
timeoutMs: job.timeoutMs,
|
|
111
|
+
failureReason: job.failureReason
|
|
110
112
|
};
|
|
111
113
|
} catch (error) {
|
|
112
114
|
log(`Error getting job ${id}: ${error}`);
|
|
@@ -119,15 +121,15 @@ var getJobsByStatus = async (pool, status, limit = 100, offset = 0) => {
|
|
|
119
121
|
const client = await pool.connect();
|
|
120
122
|
try {
|
|
121
123
|
const result = await client.query(
|
|
122
|
-
|
|
124
|
+
`SELECT id, job_type AS "jobType", payload, status, max_attempts AS "maxAttempts", attempts, priority, run_at AS "runAt", timeout_ms AS "timeoutMs", created_at AS "createdAt", updated_at AS "updatedAt", started_at AS "startedAt", completed_at AS "completedAt", last_failed_at AS "lastFailedAt", locked_at AS "lockedAt", locked_by AS "lockedBy", error_history AS "errorHistory", failure_reason AS "failureReason", next_attempt_at AS "nextAttemptAt", last_failed_at AS "lastFailedAt", last_retried_at AS "lastRetriedAt", last_cancelled_at AS "lastCancelledAt", pending_reason AS "pendingReason" FROM job_queue WHERE status = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3`,
|
|
123
125
|
[status, limit, offset]
|
|
124
126
|
);
|
|
125
127
|
log(`Found ${result.rows.length} jobs by status ${status}`);
|
|
126
|
-
return result.rows.map((
|
|
127
|
-
...
|
|
128
|
-
payload:
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
return result.rows.map((job) => ({
|
|
129
|
+
...job,
|
|
130
|
+
payload: job.payload,
|
|
131
|
+
timeoutMs: job.timeoutMs,
|
|
132
|
+
failureReason: job.failureReason
|
|
131
133
|
}));
|
|
132
134
|
} catch (error) {
|
|
133
135
|
log(`Error getting jobs by status ${status}: ${error}`);
|
|
@@ -172,7 +174,7 @@ var getNextBatch = async (pool, workerId, batchSize = 10, jobType) => {
|
|
|
172
174
|
LIMIT $2
|
|
173
175
|
FOR UPDATE SKIP LOCKED
|
|
174
176
|
)
|
|
175
|
-
RETURNING
|
|
177
|
+
RETURNING id, job_type AS "jobType", payload, status, max_attempts AS "maxAttempts", attempts, priority, run_at AS "runAt", timeout_ms AS "timeoutMs", created_at AS "createdAt", updated_at AS "updatedAt", started_at AS "startedAt", completed_at AS "completedAt", last_failed_at AS "lastFailedAt", locked_at AS "lockedAt", locked_by AS "lockedBy", error_history AS "errorHistory", failure_reason AS "failureReason", next_attempt_at AS "nextAttemptAt", last_retried_at AS "lastRetriedAt", last_cancelled_at AS "lastCancelledAt", pending_reason AS "pendingReason"
|
|
176
178
|
`,
|
|
177
179
|
params
|
|
178
180
|
);
|
|
@@ -181,10 +183,10 @@ var getNextBatch = async (pool, workerId, batchSize = 10, jobType) => {
|
|
|
181
183
|
for (const row of result.rows) {
|
|
182
184
|
await recordJobEvent(pool, row.id, "processing" /* Processing */);
|
|
183
185
|
}
|
|
184
|
-
return result.rows.map((
|
|
185
|
-
...
|
|
186
|
-
payload:
|
|
187
|
-
|
|
186
|
+
return result.rows.map((job) => ({
|
|
187
|
+
...job,
|
|
188
|
+
payload: job.payload,
|
|
189
|
+
timeoutMs: job.timeoutMs
|
|
188
190
|
}));
|
|
189
191
|
} catch (error) {
|
|
190
192
|
log(`Error getting next batch: ${error}`);
|
|
@@ -327,17 +329,17 @@ var cancelAllUpcomingJobs = async (pool, filters) => {
|
|
|
327
329
|
const params = [];
|
|
328
330
|
let paramIdx = 1;
|
|
329
331
|
if (filters) {
|
|
330
|
-
if (filters.
|
|
332
|
+
if (filters.jobType) {
|
|
331
333
|
query += ` AND job_type = $${paramIdx++}`;
|
|
332
|
-
params.push(filters.
|
|
334
|
+
params.push(filters.jobType);
|
|
333
335
|
}
|
|
334
336
|
if (filters.priority !== void 0) {
|
|
335
337
|
query += ` AND priority = $${paramIdx++}`;
|
|
336
338
|
params.push(filters.priority);
|
|
337
339
|
}
|
|
338
|
-
if (filters.
|
|
340
|
+
if (filters.runAt) {
|
|
339
341
|
query += ` AND run_at = $${paramIdx++}`;
|
|
340
|
-
params.push(filters.
|
|
342
|
+
params.push(filters.runAt);
|
|
341
343
|
}
|
|
342
344
|
}
|
|
343
345
|
query += "\nRETURNING id";
|
|
@@ -355,14 +357,14 @@ var getAllJobs = async (pool, limit = 100, offset = 0) => {
|
|
|
355
357
|
const client = await pool.connect();
|
|
356
358
|
try {
|
|
357
359
|
const result = await client.query(
|
|
358
|
-
|
|
360
|
+
`SELECT id, job_type AS "jobType", payload, status, max_attempts AS "maxAttempts", attempts, priority, run_at AS "runAt", timeout_ms AS "timeoutMs", created_at AS "createdAt", updated_at AS "updatedAt", started_at AS "startedAt", completed_at AS "completedAt", last_failed_at AS "lastFailedAt", locked_at AS "lockedAt", locked_by AS "lockedBy", error_history AS "errorHistory", failure_reason AS "failureReason", next_attempt_at AS "nextAttemptAt", last_failed_at AS "lastFailedAt", last_retried_at AS "lastRetriedAt", last_cancelled_at AS "lastCancelledAt", pending_reason AS "pendingReason" FROM job_queue ORDER BY created_at DESC LIMIT $1 OFFSET $2`,
|
|
359
361
|
[limit, offset]
|
|
360
362
|
);
|
|
361
363
|
log(`Found ${result.rows.length} jobs (all)`);
|
|
362
|
-
return result.rows.map((
|
|
363
|
-
...
|
|
364
|
-
payload:
|
|
365
|
-
|
|
364
|
+
return result.rows.map((job) => ({
|
|
365
|
+
...job,
|
|
366
|
+
payload: job.payload,
|
|
367
|
+
timeoutMs: job.timeoutMs
|
|
366
368
|
}));
|
|
367
369
|
} catch (error) {
|
|
368
370
|
log(`Error getting all jobs: ${error}`);
|
|
@@ -418,7 +420,7 @@ var getJobEvents = async (pool, jobId) => {
|
|
|
418
420
|
const client = await pool.connect();
|
|
419
421
|
try {
|
|
420
422
|
const res = await client.query(
|
|
421
|
-
|
|
423
|
+
`SELECT id, job_id AS "jobId", event_type AS "eventType", metadata, created_at AS "createdAt" FROM job_events WHERE job_id = $1 ORDER BY created_at ASC`,
|
|
422
424
|
[jobId]
|
|
423
425
|
);
|
|
424
426
|
return res.rows;
|
|
@@ -429,22 +431,22 @@ var getJobEvents = async (pool, jobId) => {
|
|
|
429
431
|
|
|
430
432
|
// src/processor.ts
|
|
431
433
|
async function processJobWithHandlers(pool, job, jobHandlers) {
|
|
432
|
-
const handler = jobHandlers[job.
|
|
434
|
+
const handler = jobHandlers[job.jobType];
|
|
433
435
|
if (!handler) {
|
|
434
436
|
await setPendingReasonForUnpickedJobs(
|
|
435
437
|
pool,
|
|
436
|
-
`No handler registered for job type: ${job.
|
|
437
|
-
job.
|
|
438
|
+
`No handler registered for job type: ${job.jobType}`,
|
|
439
|
+
job.jobType
|
|
438
440
|
);
|
|
439
441
|
await failJob(
|
|
440
442
|
pool,
|
|
441
443
|
job.id,
|
|
442
|
-
new Error(`No handler registered for job type: ${job.
|
|
444
|
+
new Error(`No handler registered for job type: ${job.jobType}`),
|
|
443
445
|
"no_handler" /* NoHandler */
|
|
444
446
|
);
|
|
445
447
|
return;
|
|
446
448
|
}
|
|
447
|
-
const timeoutMs = job.
|
|
449
|
+
const timeoutMs = job.timeoutMs ?? void 0;
|
|
448
450
|
let timeoutId;
|
|
449
451
|
const controller = new AbortController();
|
|
450
452
|
try {
|