@sqlane/core 0.1.0 → 0.1.2
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/README.md +10 -0
- package/package.json +20 -5
- package/src/create_sqlane.js +1 -0
- package/src/runner.js +137 -22
- package/src/store/mysql_final.js +23 -9
- package/src/store/postgres_final.js +27 -17
- package/src/store/store.js +7 -2
- package/types/adapters/mysql2.d.ts +13 -0
- package/types/adapters/pg.d.ts +16 -0
- package/types/backoff.d.ts +8 -0
- package/types/create_sqlane.d.ts +8 -0
- package/types/defaults.d.ts +18 -0
- package/types/define_job.d.ts +6 -0
- package/types/duration.d.ts +7 -0
- package/types/enqueue.d.ts +50 -0
- package/types/error_json.d.ts +21 -0
- package/types/errors.d.ts +129 -0
- package/types/hint_channel.d.ts +31 -0
- package/types/index.d.ts +72 -0
- package/types/migrations.d.ts +22 -0
- package/types/mutex_keys.d.ts +9 -0
- package/types/new_job.d.ts +40 -0
- package/types/payload.d.ts +10 -0
- package/types/registry.d.ts +72 -0
- package/types/runner.d.ts +92 -0
- package/types/schema/mysql.d.ts +10 -0
- package/types/schema/postgres.d.ts +10 -0
- package/types/store/mysql_enqueue.d.ts +9 -0
- package/types/store/mysql_final.d.ts +135 -0
- package/types/store/mysql_worker.d.ts +51 -0
- package/types/store/postgres_enqueue.d.ts +9 -0
- package/types/store/postgres_final.d.ts +135 -0
- package/types/store/postgres_worker.d.ts +45 -0
- package/types/store/store.d.ts +221 -0
- package/types/transient_error.d.ts +6 -0
- package/types/types.d.ts +651 -0
- package/types/validate.d.ts +76 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export type Executor = import('../types.js').Executor;
|
|
2
|
+
export type ProbeRow = import('./store.js').ProbeRow;
|
|
3
|
+
export type Candidate = import('./store.js').Candidate;
|
|
4
|
+
export type ClaimParams = import('./store.js').ClaimParams;
|
|
5
|
+
export type ClaimedJob = import('./store.js').ClaimedJob;
|
|
6
|
+
/** @typedef {import('../types.js').Executor} Executor */
|
|
7
|
+
/** @typedef {import('./store.js').ProbeRow} ProbeRow */
|
|
8
|
+
/** @typedef {import('./store.js').Candidate} Candidate */
|
|
9
|
+
/** @typedef {import('./store.js').ClaimParams} ClaimParams */
|
|
10
|
+
/** @typedef {import('./store.js').ClaimedJob} ClaimedJob */
|
|
11
|
+
/** The due jobs of each keyed name that the FIFO of the mutex keys reads */
|
|
12
|
+
export declare const MUTEX_WINDOW_SIZE = 500;
|
|
13
|
+
/**
|
|
14
|
+
* The SQL of the probe. `GROUP BY status, job_name`: the whole index prefix, else MySQL does not use a loose index
|
|
15
|
+
* scan.
|
|
16
|
+
* @param {string} p
|
|
17
|
+
* @returns {string}
|
|
18
|
+
*/
|
|
19
|
+
export declare function probeSql(p: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* The next due time of each job name with pending jobs: one index dive per pending name (loose index scan).
|
|
22
|
+
* @param {Executor} executor
|
|
23
|
+
* @param {string} p
|
|
24
|
+
* @returns {Promise<ProbeRow[]>}
|
|
25
|
+
*/
|
|
26
|
+
export declare function probe(executor: Executor, p: string): Promise<ProbeRow[]>;
|
|
27
|
+
/**
|
|
28
|
+
* The due jobs that can start now, oldest first: at most `limit` of each name. A job of a keyed name waits if one of
|
|
29
|
+
* its keys is held, or an older due job of a keyed name has it (FIFO per key over the window of the keyed names).
|
|
30
|
+
* @param {Executor} executor
|
|
31
|
+
* @param {string} p
|
|
32
|
+
* @param {Map<string, number>} limitsByName
|
|
33
|
+
* @param {string[]} keyedNames The handled names whose definition has mutex keys.
|
|
34
|
+
* @returns {Promise<Candidate[]>}
|
|
35
|
+
*/
|
|
36
|
+
export declare function findCandidates(executor: Executor, p: string, limitsByName: Map<string, number>, keyedNames: string[]): Promise<Candidate[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Claims due jobs among the candidates. Call it in a queue transaction.
|
|
39
|
+
* @param {Executor} executor
|
|
40
|
+
* @param {string} p
|
|
41
|
+
* @param {ClaimParams} params
|
|
42
|
+
* @returns {Promise<ClaimedJob[]>} In the order of run_at.
|
|
43
|
+
*/
|
|
44
|
+
export declare function claim(executor: Executor, p: string, { candidateIds, lockToken, lockedBy, leaseMs, pick }: ClaimParams): Promise<ClaimedJob[]>;
|
|
45
|
+
/**
|
|
46
|
+
* @param {Executor} executor
|
|
47
|
+
* @param {string} p
|
|
48
|
+
* @param {string[]} ids
|
|
49
|
+
* @returns {Promise<Map<string, unknown>>} The payloads by job id, as JSON gives them back.
|
|
50
|
+
*/
|
|
51
|
+
export declare function readPayloads(executor: Executor, p: string, ids: string[]): Promise<Map<string, unknown>>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inserts the jobs and their payloads.
|
|
3
|
+
* @param {import('../types.js').Executor} executor
|
|
4
|
+
* @param {string} p The table prefix.
|
|
5
|
+
* @param {import('../new_job.js').NewJob[]} jobs Their ids are distinct.
|
|
6
|
+
* @param {string} enqueueToken
|
|
7
|
+
* @returns {Promise<Set<string>>} The ids that this call created.
|
|
8
|
+
*/
|
|
9
|
+
export declare function insertJobsPostgres(executor: import('../types.js').Executor, p: string, jobs: import('../new_job.js').NewJob[], enqueueToken: string): Promise<Set<string>>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
export type Executor = import('../types.js').Executor;
|
|
2
|
+
export type OwnedJob = import('./store.js').OwnedJob;
|
|
3
|
+
export type FailureJobBuilder = import('./store.js').FailureJobBuilder;
|
|
4
|
+
export type FailureJobResult = import('./store.js').FailureJobResult;
|
|
5
|
+
/**
|
|
6
|
+
* Renews the leases of the jobs that the process runs. A row locked by another transaction is skipped: it does not
|
|
7
|
+
* block the others.
|
|
8
|
+
* @param {Executor} executor
|
|
9
|
+
* @param {string} p
|
|
10
|
+
* @param {OwnedJob[]} jobs
|
|
11
|
+
* @param {number} leaseMs
|
|
12
|
+
* @returns {Promise<Set<string>>} The ids whose lease was renewed.
|
|
13
|
+
*/
|
|
14
|
+
export declare function renewLeases(executor: Executor, p: string, jobs: OwnedJob[], leaseMs: number): Promise<Set<string>>;
|
|
15
|
+
/**
|
|
16
|
+
* Marks a timeout: the job stays running until its handler settles (`stuck` in the stats).
|
|
17
|
+
* @param {Executor} executor
|
|
18
|
+
* @param {string} p
|
|
19
|
+
* @param {OwnedJob} job
|
|
20
|
+
* @returns {Promise<boolean>} False: the lease was lost.
|
|
21
|
+
*/
|
|
22
|
+
export declare function markTimedOut(executor: Executor, p: string, job: OwnedJob): Promise<boolean>;
|
|
23
|
+
/**
|
|
24
|
+
* The jobs are done: completed until their retention ends, without their payloads; their keys are freed. One
|
|
25
|
+
* statement for many jobs.
|
|
26
|
+
* @param {Executor} executor
|
|
27
|
+
* @param {string} p
|
|
28
|
+
* @param {import('./store.js').FinishedJob[]} jobs
|
|
29
|
+
* @returns {Promise<number>} The jobs that this call completed: the others lost their lease, or an earlier try
|
|
30
|
+
* committed.
|
|
31
|
+
*/
|
|
32
|
+
export declare function completeJobs(executor: Executor, p: string, jobs: import('./store.js').FinishedJob[]): Promise<number>;
|
|
33
|
+
/**
|
|
34
|
+
* The attempt failed: pending again after the delay, one more attempt used; its keys are freed.
|
|
35
|
+
* @param {Executor} executor
|
|
36
|
+
* @param {string} p
|
|
37
|
+
* @param {OwnedJob} job
|
|
38
|
+
* @param {{ delayMs: number, error: import('../error_json.js').ErrorJson }} params
|
|
39
|
+
* @returns {Promise<boolean>} False: no change.
|
|
40
|
+
*/
|
|
41
|
+
export declare function retryJob(executor: Executor, p: string, job: OwnedJob, { delayMs, error }: {
|
|
42
|
+
delayMs: number;
|
|
43
|
+
error: import('../error_json.js').ErrorJson;
|
|
44
|
+
}): Promise<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* The job fails for good: failed until its retention ends, with its payload; its keys are freed; its failure job is
|
|
47
|
+
* added in the same transaction.
|
|
48
|
+
* @param {Executor} executor
|
|
49
|
+
* @param {string} p
|
|
50
|
+
* @param {OwnedJob} job
|
|
51
|
+
* @param {{ error: import('../error_json.js').ErrorJson, buildFailureJob: FailureJobBuilder }} params
|
|
52
|
+
* @returns {Promise<{ changed: boolean, failureJob: FailureJobResult | null }>}
|
|
53
|
+
*/
|
|
54
|
+
export declare function failJob(executor: Executor, p: string, job: OwnedJob, { error, buildFailureJob }: {
|
|
55
|
+
error: import('../error_json.js').ErrorJson;
|
|
56
|
+
buildFailureJob: FailureJobBuilder;
|
|
57
|
+
}): Promise<{
|
|
58
|
+
changed: boolean;
|
|
59
|
+
failureJob: FailureJobResult | null;
|
|
60
|
+
}>;
|
|
61
|
+
/**
|
|
62
|
+
* The job is released, without an attempt used: pending again after the delay.
|
|
63
|
+
* @param {Executor} executor
|
|
64
|
+
* @param {string} p
|
|
65
|
+
* @param {OwnedJob} job
|
|
66
|
+
* @param {{ delayMs: number, lingerMs: number }} params lingerMs: its keys stay held this long (its handler still
|
|
67
|
+
* runs); 0: they are freed.
|
|
68
|
+
* @returns {Promise<boolean>} False: no change.
|
|
69
|
+
*/
|
|
70
|
+
export declare function releaseJob(executor: Executor, p: string, job: OwnedJob, { delayMs, lingerMs }: {
|
|
71
|
+
delayMs: number;
|
|
72
|
+
lingerMs: number;
|
|
73
|
+
}): Promise<boolean>;
|
|
74
|
+
/**
|
|
75
|
+
* @param {Executor} executor
|
|
76
|
+
* @param {string} p
|
|
77
|
+
* @param {number} limit
|
|
78
|
+
* @returns {Promise<{ id: string, name: string }[]>} The running jobs whose lease ended, the oldest first.
|
|
79
|
+
*/
|
|
80
|
+
export declare function findStaleJobs(executor: Executor, p: string, limit: number): Promise<{
|
|
81
|
+
id: string;
|
|
82
|
+
name: string;
|
|
83
|
+
}[]>;
|
|
84
|
+
/**
|
|
85
|
+
* A running job whose lease ended: one more stall, pending again after 30 s × 2^stalls (at most 1 h); after maxStalls,
|
|
86
|
+
* it fails for good. Its keys linger for one lease: its old handler may still run.
|
|
87
|
+
* @param {Executor} executor
|
|
88
|
+
* @param {string} p
|
|
89
|
+
* @param {string} id
|
|
90
|
+
* @param {{ leaseMs: number, buildFailureJob: FailureJobBuilder }} params
|
|
91
|
+
* @returns {Promise<{ result: 'released' | 'failed' | null, failureJob: FailureJobResult | null }>} null: not stale
|
|
92
|
+
* (any more).
|
|
93
|
+
*/
|
|
94
|
+
export declare function recoverStaleJob(executor: Executor, p: string, id: string, { leaseMs, buildFailureJob }: {
|
|
95
|
+
leaseMs: number;
|
|
96
|
+
buildFailureJob: FailureJobBuilder;
|
|
97
|
+
}): Promise<{
|
|
98
|
+
result: 'released' | 'failed' | null;
|
|
99
|
+
failureJob: FailureJobResult | null;
|
|
100
|
+
}>;
|
|
101
|
+
/**
|
|
102
|
+
* Deletes the ended lingers, and the holds without their running job (from a manual change, or old code).
|
|
103
|
+
* @param {Executor} executor
|
|
104
|
+
* @param {string} p
|
|
105
|
+
* @param {number} limit
|
|
106
|
+
* @returns {Promise<{ lingers: number, orphans: number }>}
|
|
107
|
+
*/
|
|
108
|
+
export declare function sweepMutexes(executor: Executor, p: string, limit: number): Promise<{
|
|
109
|
+
lingers: number;
|
|
110
|
+
orphans: number;
|
|
111
|
+
}>;
|
|
112
|
+
/**
|
|
113
|
+
* Deletes a batch of completed and failed jobs whose retention ended, with their payloads. SKIP LOCKED: processes
|
|
114
|
+
* share the work.
|
|
115
|
+
* @param {Executor} executor
|
|
116
|
+
* @param {string} p
|
|
117
|
+
* @param {number} limit
|
|
118
|
+
* @returns {Promise<number>} The deleted jobs.
|
|
119
|
+
*/
|
|
120
|
+
export declare function deleteExpiredJobs(executor: Executor, p: string, limit: number): Promise<number>;
|
|
121
|
+
/**
|
|
122
|
+
* For drain({ includeDelayed }): the pending jobs of the names are due now.
|
|
123
|
+
* @param {Executor} executor
|
|
124
|
+
* @param {string} p
|
|
125
|
+
* @param {string[]} names
|
|
126
|
+
* @returns {Promise<void>}
|
|
127
|
+
*/
|
|
128
|
+
export declare function makeDue(executor: Executor, p: string, names: string[]): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* The counts per job name, for alerts such as "queue stuck".
|
|
131
|
+
* @param {Executor} executor
|
|
132
|
+
* @param {string} p
|
|
133
|
+
* @returns {Promise<import('../types.js').JobStats[]>}
|
|
134
|
+
*/
|
|
135
|
+
export declare function getStats(executor: Executor, p: string): Promise<import('../types.js').JobStats[]>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type Executor = import('../types.js').Executor;
|
|
2
|
+
export type ProbeRow = import('./store.js').ProbeRow;
|
|
3
|
+
export type Candidate = import('./store.js').Candidate;
|
|
4
|
+
export type ClaimParams = import('./store.js').ClaimParams;
|
|
5
|
+
export type ClaimedJob = import('./store.js').ClaimedJob;
|
|
6
|
+
/** @typedef {import('../types.js').Executor} Executor */
|
|
7
|
+
/** @typedef {import('./store.js').ProbeRow} ProbeRow */
|
|
8
|
+
/** @typedef {import('./store.js').Candidate} Candidate */
|
|
9
|
+
/** @typedef {import('./store.js').ClaimParams} ClaimParams */
|
|
10
|
+
/** @typedef {import('./store.js').ClaimedJob} ClaimedJob */
|
|
11
|
+
/** The due jobs of each keyed name that the FIFO of the mutex keys reads */
|
|
12
|
+
export declare const MUTEX_WINDOW_SIZE = 500;
|
|
13
|
+
/**
|
|
14
|
+
* The next due time of each job name with pending jobs. PostgreSQL has no loose index scan: a recursive CTE skips from
|
|
15
|
+
* one pending name to the next on the partial index, two index probes per pending name.
|
|
16
|
+
* @param {Executor} executor
|
|
17
|
+
* @param {string} p
|
|
18
|
+
* @returns {Promise<ProbeRow[]>}
|
|
19
|
+
*/
|
|
20
|
+
export declare function probe(executor: Executor, p: string): Promise<ProbeRow[]>;
|
|
21
|
+
/**
|
|
22
|
+
* The due jobs that can start now, oldest first: at most `limit` of each name. A job of a keyed name waits if one of
|
|
23
|
+
* its keys is held, or an older due job of a keyed name has it (FIFO per key over the window of the keyed names).
|
|
24
|
+
* @param {Executor} executor
|
|
25
|
+
* @param {string} p
|
|
26
|
+
* @param {Map<string, number>} limitsByName
|
|
27
|
+
* @param {string[]} keyedNames The handled names whose definition has mutex keys.
|
|
28
|
+
* @returns {Promise<Candidate[]>}
|
|
29
|
+
*/
|
|
30
|
+
export declare function findCandidates(executor: Executor, p: string, limitsByName: Map<string, number>, keyedNames: string[]): Promise<Candidate[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Claims due jobs among the candidates. Call it in a queue transaction.
|
|
33
|
+
* @param {Executor} executor
|
|
34
|
+
* @param {string} p
|
|
35
|
+
* @param {ClaimParams} params
|
|
36
|
+
* @returns {Promise<ClaimedJob[]>} In the order of run_at.
|
|
37
|
+
*/
|
|
38
|
+
export declare function claim(executor: Executor, p: string, { candidateIds, lockToken, lockedBy, leaseMs, pick }: ClaimParams): Promise<ClaimedJob[]>;
|
|
39
|
+
/**
|
|
40
|
+
* @param {Executor} executor
|
|
41
|
+
* @param {string} p
|
|
42
|
+
* @param {string[]} ids
|
|
43
|
+
* @returns {Promise<Map<string, unknown>>} The payloads by job id, as JSON gives them back.
|
|
44
|
+
*/
|
|
45
|
+
export declare function readPayloads(executor: Executor, p: string, ids: string[]): Promise<Map<string, unknown>>;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
export type ProbeRow = {
|
|
2
|
+
/**
|
|
3
|
+
* A job name with pending jobs.
|
|
4
|
+
*/
|
|
5
|
+
name: string;
|
|
6
|
+
/**
|
|
7
|
+
* Until its oldest pending job is due: 0 or less means due now.
|
|
8
|
+
*/
|
|
9
|
+
delayMs: number;
|
|
10
|
+
};
|
|
11
|
+
export type Candidate = {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
runAtMs: number;
|
|
15
|
+
};
|
|
16
|
+
export type ClaimedJob = {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
mutexKeys: string[];
|
|
20
|
+
/**
|
|
21
|
+
* The failed attempts so far.
|
|
22
|
+
*/
|
|
23
|
+
attempts: number;
|
|
24
|
+
maxAttempts: number;
|
|
25
|
+
stalls: number;
|
|
26
|
+
maxStalls: number;
|
|
27
|
+
failureJob: string | null;
|
|
28
|
+
enqueuedAt: Date;
|
|
29
|
+
/**
|
|
30
|
+
* Since it was due.
|
|
31
|
+
*/
|
|
32
|
+
waitedMs: number;
|
|
33
|
+
lockToken: string;
|
|
34
|
+
};
|
|
35
|
+
export type ClaimParams = {
|
|
36
|
+
candidateIds: string[];
|
|
37
|
+
/**
|
|
38
|
+
* Of this claim.
|
|
39
|
+
*/
|
|
40
|
+
lockToken: string;
|
|
41
|
+
/**
|
|
42
|
+
* The process.
|
|
43
|
+
*/
|
|
44
|
+
lockedBy: string;
|
|
45
|
+
leaseMs: number;
|
|
46
|
+
/**
|
|
47
|
+
* The jobs to take among the locked
|
|
48
|
+
* ones (in the order of run_at): the free slots, the free keys. The keys of the picked jobs must be distinct.
|
|
49
|
+
*/
|
|
50
|
+
pick: (locked: ClaimedJob[], busyKeys: Set<string>) => ClaimedJob[];
|
|
51
|
+
};
|
|
52
|
+
export type OwnedJob = {
|
|
53
|
+
id: string;
|
|
54
|
+
lockToken: string;
|
|
55
|
+
};
|
|
56
|
+
export type FinishedJob = OwnedJob & {
|
|
57
|
+
mutexKeys: readonly string[];
|
|
58
|
+
};
|
|
59
|
+
export type FailedJob = {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
/**
|
|
63
|
+
* Null: its payload is missing.
|
|
64
|
+
*/
|
|
65
|
+
payload: unknown;
|
|
66
|
+
attempt: number;
|
|
67
|
+
maxAttempts: number;
|
|
68
|
+
/**
|
|
69
|
+
* The name of its failure job.
|
|
70
|
+
*/
|
|
71
|
+
failureJob: string;
|
|
72
|
+
error: import('../error_json.js').ErrorJson;
|
|
73
|
+
};
|
|
74
|
+
export type FailureJobBuilder = (failed: FailedJob) => import('../new_job.js').NewJob;
|
|
75
|
+
export type FailureJobResult = {
|
|
76
|
+
added: import('../new_job.js').NewJob;
|
|
77
|
+
} | {
|
|
78
|
+
notAdded: unknown;
|
|
79
|
+
};
|
|
80
|
+
export type Store = {
|
|
81
|
+
probe: () => Promise<ProbeRow[]>;
|
|
82
|
+
findCandidates: (limitsByName: Map<string, number>, keyedNames: string[]) => Promise<Candidate[]>;
|
|
83
|
+
/**
|
|
84
|
+
* In a queue transaction of its own.
|
|
85
|
+
*/
|
|
86
|
+
claim: (params: ClaimParams) => Promise<ClaimedJob[]>;
|
|
87
|
+
readPayloads: (ids: string[]) => Promise<Map<string, unknown>>;
|
|
88
|
+
renewLeases: (jobs: OwnedJob[], leaseMs: number) => Promise<Set<string>>;
|
|
89
|
+
markTimedOut: (job: OwnedJob) => Promise<boolean>;
|
|
90
|
+
/**
|
|
91
|
+
* In one transaction: the jobs that it completed.
|
|
92
|
+
*/
|
|
93
|
+
completeJobs: (jobs: FinishedJob[]) => Promise<number>;
|
|
94
|
+
retryJob: (job: OwnedJob, params: {
|
|
95
|
+
delayMs: number;
|
|
96
|
+
error: import('../error_json.js').ErrorJson;
|
|
97
|
+
}) => Promise<boolean>;
|
|
98
|
+
failJob: (job: OwnedJob, params: {
|
|
99
|
+
error: import('../error_json.js').ErrorJson;
|
|
100
|
+
buildFailureJob: FailureJobBuilder;
|
|
101
|
+
}) => Promise<{
|
|
102
|
+
changed: boolean;
|
|
103
|
+
failureJob: FailureJobResult | null;
|
|
104
|
+
}>;
|
|
105
|
+
releaseJob: (job: OwnedJob, params: {
|
|
106
|
+
delayMs: number;
|
|
107
|
+
lingerMs: number;
|
|
108
|
+
}) => Promise<boolean>;
|
|
109
|
+
findStaleJobs: (limit: number) => Promise<{
|
|
110
|
+
id: string;
|
|
111
|
+
name: string;
|
|
112
|
+
}[]>;
|
|
113
|
+
recoverStaleJob: (id: string, params: {
|
|
114
|
+
leaseMs: number;
|
|
115
|
+
buildFailureJob: FailureJobBuilder;
|
|
116
|
+
}) => Promise<{
|
|
117
|
+
result: 'released' | 'failed' | null;
|
|
118
|
+
failureJob: FailureJobResult | null;
|
|
119
|
+
}>;
|
|
120
|
+
sweepMutexes: (limit: number) => Promise<{
|
|
121
|
+
lingers: number;
|
|
122
|
+
orphans: number;
|
|
123
|
+
}>;
|
|
124
|
+
deleteExpiredJobs: (limit: number) => Promise<number>;
|
|
125
|
+
/**
|
|
126
|
+
* For drain({ includeDelayed }).
|
|
127
|
+
*/
|
|
128
|
+
makeDue: (names: string[]) => Promise<void>;
|
|
129
|
+
getStats: () => Promise<import('../types.js').JobStats[]>;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* @typedef {object} ProbeRow
|
|
133
|
+
* @property {string} name A job name with pending jobs.
|
|
134
|
+
* @property {number} delayMs Until its oldest pending job is due: 0 or less means due now.
|
|
135
|
+
*/
|
|
136
|
+
/**
|
|
137
|
+
* @typedef {object} Candidate
|
|
138
|
+
* @property {string} id
|
|
139
|
+
* @property {string} name
|
|
140
|
+
* @property {number} runAtMs
|
|
141
|
+
*/
|
|
142
|
+
/**
|
|
143
|
+
* A job that a claim locked, and then claimed: it runs.
|
|
144
|
+
* @typedef {object} ClaimedJob
|
|
145
|
+
* @property {string} id
|
|
146
|
+
* @property {string} name
|
|
147
|
+
* @property {string[]} mutexKeys
|
|
148
|
+
* @property {number} attempts The failed attempts so far.
|
|
149
|
+
* @property {number} maxAttempts
|
|
150
|
+
* @property {number} stalls
|
|
151
|
+
* @property {number} maxStalls
|
|
152
|
+
* @property {string | null} failureJob
|
|
153
|
+
* @property {Date} enqueuedAt
|
|
154
|
+
* @property {number} waitedMs Since it was due.
|
|
155
|
+
* @property {string} lockToken
|
|
156
|
+
*/
|
|
157
|
+
/**
|
|
158
|
+
* @typedef {object} ClaimParams
|
|
159
|
+
* @property {string[]} candidateIds
|
|
160
|
+
* @property {string} lockToken Of this claim.
|
|
161
|
+
* @property {string} lockedBy The process.
|
|
162
|
+
* @property {number} leaseMs
|
|
163
|
+
* @property {(locked: ClaimedJob[], busyKeys: Set<string>) => ClaimedJob[]} pick The jobs to take among the locked
|
|
164
|
+
* ones (in the order of run_at): the free slots, the free keys. The keys of the picked jobs must be distinct.
|
|
165
|
+
*/
|
|
166
|
+
/**
|
|
167
|
+
* A job that this process claimed: every write of it checks the lock token.
|
|
168
|
+
* @typedef {object} OwnedJob
|
|
169
|
+
* @property {string} id
|
|
170
|
+
* @property {string} lockToken
|
|
171
|
+
*/
|
|
172
|
+
/**
|
|
173
|
+
* A job that this process ran, with its keys.
|
|
174
|
+
* @typedef {OwnedJob & { mutexKeys: readonly string[] }} FinishedJob
|
|
175
|
+
*/
|
|
176
|
+
/**
|
|
177
|
+
* The job that fails for good, as the failure job gets it.
|
|
178
|
+
* @typedef {object} FailedJob
|
|
179
|
+
* @property {string} id
|
|
180
|
+
* @property {string} name
|
|
181
|
+
* @property {unknown} payload Null: its payload is missing.
|
|
182
|
+
* @property {number} attempt
|
|
183
|
+
* @property {number} maxAttempts
|
|
184
|
+
* @property {string} failureJob The name of its failure job.
|
|
185
|
+
* @property {import('../error_json.js').ErrorJson} error
|
|
186
|
+
*/
|
|
187
|
+
/**
|
|
188
|
+
* Builds the failure job: its options from its definition, else the defaults; no failure job of its own.
|
|
189
|
+
* @typedef {(failed: FailedJob) => import('../new_job.js').NewJob} FailureJobBuilder
|
|
190
|
+
*/
|
|
191
|
+
/** @typedef {{ added: import('../new_job.js').NewJob } | { notAdded: unknown }} FailureJobResult */
|
|
192
|
+
/**
|
|
193
|
+
* @typedef {object} Store
|
|
194
|
+
* @property {() => Promise<ProbeRow[]>} probe
|
|
195
|
+
* @property {(limitsByName: Map<string, number>, keyedNames: string[]) => Promise<Candidate[]>} findCandidates
|
|
196
|
+
* @property {(params: ClaimParams) => Promise<ClaimedJob[]>} claim In a queue transaction of its own.
|
|
197
|
+
* @property {(ids: string[]) => Promise<Map<string, unknown>>} readPayloads
|
|
198
|
+
* @property {(jobs: OwnedJob[], leaseMs: number) => Promise<Set<string>>} renewLeases
|
|
199
|
+
* @property {(job: OwnedJob) => Promise<boolean>} markTimedOut
|
|
200
|
+
* @property {(jobs: FinishedJob[]) => Promise<number>} completeJobs In one transaction: the jobs that it completed.
|
|
201
|
+
* @property {(job: OwnedJob, params: { delayMs: number, error: import('../error_json.js').ErrorJson })
|
|
202
|
+
* => Promise<boolean>} retryJob
|
|
203
|
+
* @property {(
|
|
204
|
+
* job: OwnedJob,
|
|
205
|
+
* params: { error: import('../error_json.js').ErrorJson, buildFailureJob: FailureJobBuilder },
|
|
206
|
+
* ) => Promise<{ changed: boolean, failureJob: FailureJobResult | null }>} failJob
|
|
207
|
+
* @property {(job: OwnedJob, params: { delayMs: number, lingerMs: number }) => Promise<boolean>} releaseJob
|
|
208
|
+
* @property {(limit: number) => Promise<{ id: string, name: string }[]>} findStaleJobs
|
|
209
|
+
* @property {(id: string, params: { leaseMs: number, buildFailureJob: FailureJobBuilder })
|
|
210
|
+
* => Promise<{ result: 'released' | 'failed' | null, failureJob: FailureJobResult | null }>} recoverStaleJob
|
|
211
|
+
* @property {(limit: number) => Promise<{ lingers: number, orphans: number }>} sweepMutexes
|
|
212
|
+
* @property {(limit: number) => Promise<number>} deleteExpiredJobs
|
|
213
|
+
* @property {(names: string[]) => Promise<void>} makeDue For drain({ includeDelayed }).
|
|
214
|
+
* @property {() => Promise<import('../types.js').JobStats[]>} getStats
|
|
215
|
+
*/
|
|
216
|
+
/**
|
|
217
|
+
* @param {import('../types.js').Adapter<any>} adapter
|
|
218
|
+
* @param {string} tablePrefix Checked.
|
|
219
|
+
* @returns {Store}
|
|
220
|
+
*/
|
|
221
|
+
export declare function createStore(adapter: import('../types.js').Adapter<any>, tablePrefix: string): Store;
|