@workglow/job-queue 0.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +694 -0
- package/dist/browser.js +1075 -0
- package/dist/browser.js.map +20 -0
- package/dist/bun.js +1375 -0
- package/dist/bun.js.map +22 -0
- package/dist/common-server.d.ts +9 -0
- package/dist/common-server.d.ts.map +1 -0
- package/dist/common.d.ts +18 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/job/IJobQueue.d.ts +160 -0
- package/dist/job/IJobQueue.d.ts.map +1 -0
- package/dist/job/Job.d.ts +87 -0
- package/dist/job/Job.d.ts.map +1 -0
- package/dist/job/JobError.d.ts +61 -0
- package/dist/job/JobError.d.ts.map +1 -0
- package/dist/job/JobQueue.d.ts +272 -0
- package/dist/job/JobQueue.d.ts.map +1 -0
- package/dist/job/JobQueueEventListeners.d.ts +30 -0
- package/dist/job/JobQueueEventListeners.d.ts.map +1 -0
- package/dist/limiter/CompositeLimiter.d.ts +18 -0
- package/dist/limiter/CompositeLimiter.d.ts.map +1 -0
- package/dist/limiter/ConcurrencyLimiter.d.ts +24 -0
- package/dist/limiter/ConcurrencyLimiter.d.ts.map +1 -0
- package/dist/limiter/DelayLimiter.d.ts +18 -0
- package/dist/limiter/DelayLimiter.d.ts.map +1 -0
- package/dist/limiter/EvenlySpacedRateLimiter.d.ts +35 -0
- package/dist/limiter/EvenlySpacedRateLimiter.d.ts.map +1 -0
- package/dist/limiter/ILimiter.d.ts +27 -0
- package/dist/limiter/ILimiter.d.ts.map +1 -0
- package/dist/limiter/InMemoryRateLimiter.d.ts +32 -0
- package/dist/limiter/InMemoryRateLimiter.d.ts.map +1 -0
- package/dist/limiter/NullLimiter.d.ts +19 -0
- package/dist/limiter/NullLimiter.d.ts.map +1 -0
- package/dist/limiter/PostgresRateLimiter.d.ts +53 -0
- package/dist/limiter/PostgresRateLimiter.d.ts.map +1 -0
- package/dist/limiter/SqliteRateLimiter.d.ts +44 -0
- package/dist/limiter/SqliteRateLimiter.d.ts.map +1 -0
- package/dist/node.js +1374 -0
- package/dist/node.js.map +22 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { IQueueStorage, JobStorageFormat } from "@workglow/storage";
|
|
7
|
+
import { EventEmitter } from "@workglow/util";
|
|
8
|
+
import { ILimiter } from "../limiter/ILimiter";
|
|
9
|
+
import { IJobQueue, JobQueueOptions, JobStatus, QueueMode } from "./IJobQueue";
|
|
10
|
+
import { Job, JobConstructorParam } from "./Job";
|
|
11
|
+
import { JobError } from "./JobError";
|
|
12
|
+
import { JobProgressListener, JobQueueEventListener, JobQueueEventListeners, JobQueueEventParameters, JobQueueEvents } from "./JobQueueEventListeners";
|
|
13
|
+
/**
|
|
14
|
+
* Statistics tracked for the job queue
|
|
15
|
+
*/
|
|
16
|
+
export interface JobQueueStats {
|
|
17
|
+
totalJobs: number;
|
|
18
|
+
completedJobs: number;
|
|
19
|
+
failedJobs: number;
|
|
20
|
+
abortedJobs: number;
|
|
21
|
+
retriedJobs: number;
|
|
22
|
+
disabledJobs: number;
|
|
23
|
+
averageProcessingTime?: number;
|
|
24
|
+
lastUpdateTime: Date;
|
|
25
|
+
}
|
|
26
|
+
type JobClass<Input, Output> = new (param: JobConstructorParam<Input, Output>) => Job<Input, Output>;
|
|
27
|
+
/**
|
|
28
|
+
* Base class for implementing job queues with different storage backends.
|
|
29
|
+
*/
|
|
30
|
+
export declare class JobQueue<Input, Output, QueueJob extends Job<Input, Output> = Job<Input, Output>> implements IJobQueue<Input, Output> {
|
|
31
|
+
/**
|
|
32
|
+
* The name of the queue
|
|
33
|
+
*/
|
|
34
|
+
readonly queueName: string;
|
|
35
|
+
/**
|
|
36
|
+
* The class of the job to be used in the queue
|
|
37
|
+
*/
|
|
38
|
+
readonly jobClass: JobClass<Input, Output>;
|
|
39
|
+
/**
|
|
40
|
+
* The options for the queue
|
|
41
|
+
*/
|
|
42
|
+
protected options: JobQueueOptions<Input, Output>;
|
|
43
|
+
constructor(queueName: string, jobClass: JobClass<Input, Output>, options: JobQueueOptions<Input, Output>);
|
|
44
|
+
/**
|
|
45
|
+
* Gets a job from the queue
|
|
46
|
+
* @param id The ID of the job to get
|
|
47
|
+
*/
|
|
48
|
+
get(id: unknown): Promise<Job<Input, Output> | undefined>;
|
|
49
|
+
/**
|
|
50
|
+
* Adds a job to the queue
|
|
51
|
+
* @param job The job to add
|
|
52
|
+
*/
|
|
53
|
+
add(job: QueueJob): Promise<unknown>;
|
|
54
|
+
/**
|
|
55
|
+
* Gets the next job from the queue
|
|
56
|
+
*/
|
|
57
|
+
next(): Promise<Job<Input, Output> | undefined>;
|
|
58
|
+
/**
|
|
59
|
+
* Peek into the queue
|
|
60
|
+
* @param status The status of the job to peek at
|
|
61
|
+
* @param num The number of jobs to peek at
|
|
62
|
+
*/
|
|
63
|
+
peek(status?: JobStatus, num?: number): Promise<Job<Input, Output>[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Gets the size of the queue
|
|
66
|
+
* @param status The status of the jobs to get the size of
|
|
67
|
+
*/
|
|
68
|
+
size(status?: JobStatus): Promise<number>;
|
|
69
|
+
/**
|
|
70
|
+
* Deletes a job from the queue
|
|
71
|
+
* @param id The ID of the job to delete
|
|
72
|
+
*/
|
|
73
|
+
delete(id: unknown): Promise<void>;
|
|
74
|
+
disable(id: unknown): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Returns current queue statistics
|
|
77
|
+
*/
|
|
78
|
+
getStats(): JobQueueStats;
|
|
79
|
+
/**
|
|
80
|
+
* Gets the output for an input
|
|
81
|
+
* @param input The input to get the output for
|
|
82
|
+
*/
|
|
83
|
+
outputForInput(input: Input): Promise<Output | null>;
|
|
84
|
+
/**
|
|
85
|
+
* Executes a job with the provided abort signal.
|
|
86
|
+
* Can be overridden by implementations to add custom execution logic.
|
|
87
|
+
*/
|
|
88
|
+
executeJob(job: Job<Input, Output>, signal: AbortSignal): Promise<Output>;
|
|
89
|
+
/**
|
|
90
|
+
* Returns a promise that resolves when the job completes
|
|
91
|
+
*/
|
|
92
|
+
waitFor(jobId: unknown): Promise<Output | undefined>;
|
|
93
|
+
/**
|
|
94
|
+
* Reconstructs an error instance from a stored failed job
|
|
95
|
+
*/
|
|
96
|
+
protected buildErrorFromJob(job: Job<Input, Output>): JobError;
|
|
97
|
+
/**
|
|
98
|
+
* Updates the progress of a job
|
|
99
|
+
* @param jobId - The ID of the job to update
|
|
100
|
+
* @param progress - Progress value between 0 and 100
|
|
101
|
+
* @param message - Optional message describing the current progress state
|
|
102
|
+
* @param details - Optional structured data about the progress
|
|
103
|
+
* @returns A promise that resolves when the progress is updated
|
|
104
|
+
* @note If the job is completed, failed, or aborted, the progress will not be updated
|
|
105
|
+
*/
|
|
106
|
+
updateProgress(jobId: unknown, progress: number, message?: string, details?: Record<string, any> | null): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Adds a progress listener for a specific job
|
|
109
|
+
* @param jobId - The ID of the job to listen to
|
|
110
|
+
* @param listener - The callback function to be called when progress updates occur
|
|
111
|
+
* @returns A cleanup function to remove the listener
|
|
112
|
+
*/
|
|
113
|
+
onJobProgress(jobId: unknown, listener: JobProgressListener): () => void;
|
|
114
|
+
/**
|
|
115
|
+
* Starts the job queue based on its operating mode
|
|
116
|
+
*/
|
|
117
|
+
start(mode?: QueueMode): Promise<this>;
|
|
118
|
+
/**
|
|
119
|
+
* Stops the job queue and aborts all active jobs
|
|
120
|
+
*/
|
|
121
|
+
stop(): Promise<this>;
|
|
122
|
+
/**
|
|
123
|
+
* Clears all jobs and resets queue state
|
|
124
|
+
*/
|
|
125
|
+
clear(): Promise<this>;
|
|
126
|
+
/**
|
|
127
|
+
* Restarts the job queue
|
|
128
|
+
*/
|
|
129
|
+
restart(): Promise<this>;
|
|
130
|
+
/**
|
|
131
|
+
* Aborts all jobs in a job run
|
|
132
|
+
*/
|
|
133
|
+
abortJobRun(jobRunId: string): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Gets jobs by run ID
|
|
136
|
+
* @param runId The ID of the run to get jobs for
|
|
137
|
+
*/
|
|
138
|
+
getJobsByRunId(runId: string): Promise<Job<Input, Output>[]>;
|
|
139
|
+
/**
|
|
140
|
+
* Registers an event listener for job queue events
|
|
141
|
+
*/
|
|
142
|
+
on<Event extends JobQueueEvents>(event: Event, listener: JobQueueEventListener<Event>): void;
|
|
143
|
+
/**
|
|
144
|
+
* Removes an event listener for job queue events
|
|
145
|
+
*/
|
|
146
|
+
off<Event extends JobQueueEvents>(event: Event, listener: JobQueueEventListener<Event>): void;
|
|
147
|
+
/**
|
|
148
|
+
* Adds an event listener for job queue events that will be called only once
|
|
149
|
+
*/
|
|
150
|
+
once<Event extends JobQueueEvents>(event: Event, listener: JobQueueEventListener<Event>): void;
|
|
151
|
+
/**
|
|
152
|
+
* Returns a promise that resolves when the event is emitted
|
|
153
|
+
*/
|
|
154
|
+
waitOn<Event extends JobQueueEvents>(event: Event): Promise<JobQueueEventParameters<Event, Input, Output>>;
|
|
155
|
+
/**
|
|
156
|
+
* The limiter for the queue
|
|
157
|
+
*/
|
|
158
|
+
protected readonly limiter: ILimiter;
|
|
159
|
+
/**
|
|
160
|
+
* The storage for the queue
|
|
161
|
+
*/
|
|
162
|
+
protected readonly storage: IQueueStorage<Input, Output>;
|
|
163
|
+
/**
|
|
164
|
+
* Whether the queue is running
|
|
165
|
+
*/
|
|
166
|
+
protected running: boolean;
|
|
167
|
+
/**
|
|
168
|
+
* The stats for the queue
|
|
169
|
+
*/
|
|
170
|
+
protected stats: JobQueueStats;
|
|
171
|
+
/**
|
|
172
|
+
* The event emitter for the queue
|
|
173
|
+
*/
|
|
174
|
+
protected events: EventEmitter<JobQueueEventListeners<Input, Output>>;
|
|
175
|
+
/**
|
|
176
|
+
* The map of jobs to their promises for this worker instance
|
|
177
|
+
*/
|
|
178
|
+
protected activeJobAbortControllers: Map<unknown, AbortController>;
|
|
179
|
+
/**
|
|
180
|
+
* Map of jobs to their promises for this worker instance
|
|
181
|
+
* If this is both a server and client we can short-circuit
|
|
182
|
+
* job aborting, wait on job completion, etc.
|
|
183
|
+
*/
|
|
184
|
+
protected activeJobPromises: Map<unknown, Array<{
|
|
185
|
+
resolve: (value?: any) => void;
|
|
186
|
+
reject: (err: JobError) => void;
|
|
187
|
+
}>>;
|
|
188
|
+
protected processingTimes: Map<unknown, number>;
|
|
189
|
+
protected mode: QueueMode;
|
|
190
|
+
protected jobProgressListeners: Map<unknown, Set<JobProgressListener>>;
|
|
191
|
+
protected lastKnownProgress: Map<unknown, {
|
|
192
|
+
progress: number;
|
|
193
|
+
message: string;
|
|
194
|
+
details: Record<string, any> | null;
|
|
195
|
+
}>;
|
|
196
|
+
/**
|
|
197
|
+
* Saves the progress for a job
|
|
198
|
+
* @param id The ID of the job to save progress for
|
|
199
|
+
* @param progress The progress of the job
|
|
200
|
+
* @param message The message of the job
|
|
201
|
+
* @param details The details of the job
|
|
202
|
+
*/
|
|
203
|
+
private saveProgress;
|
|
204
|
+
/**
|
|
205
|
+
* Creates an abort controller for a job and adds it to the activeJobSignals map
|
|
206
|
+
*/
|
|
207
|
+
protected createAbortController(jobId: unknown): AbortController;
|
|
208
|
+
/**
|
|
209
|
+
* Validates the state of a job before processing
|
|
210
|
+
*/
|
|
211
|
+
protected validateJobState(job: Job<Input, Output>): Promise<void>;
|
|
212
|
+
/**
|
|
213
|
+
* Normalizes different types of errors into JobError instances
|
|
214
|
+
*/
|
|
215
|
+
protected normalizeError(err: any): JobError;
|
|
216
|
+
/**
|
|
217
|
+
* Updates average processing time statistics
|
|
218
|
+
*/
|
|
219
|
+
protected updateAverageProcessingTime(): void;
|
|
220
|
+
/**
|
|
221
|
+
* Emits updated statistics
|
|
222
|
+
*/
|
|
223
|
+
protected emitStatsUpdate(): void;
|
|
224
|
+
protected announceProgress(jobId: unknown, progress: number, message: string, details: Record<string, any> | null): void;
|
|
225
|
+
/**
|
|
226
|
+
* Creates a new job instance from the provided database results.
|
|
227
|
+
* @param details - The job data from the database
|
|
228
|
+
* @returns A new Job instance with populated properties
|
|
229
|
+
*/
|
|
230
|
+
protected storageToClass(details: JobStorageFormat<Input, Output>): Job<Input, Output>;
|
|
231
|
+
/**
|
|
232
|
+
* Converts a Job instance to a JobDetails object
|
|
233
|
+
* @param job - The Job instance to convert
|
|
234
|
+
* @returns A JobDetails object with the same properties as the Job instance
|
|
235
|
+
*/
|
|
236
|
+
classToStorage(job: Job<Input, Output>): JobStorageFormat<Input, Output>;
|
|
237
|
+
protected rescheduleJob(job: Job<Input, Output>, retryDate?: Date): Promise<void>;
|
|
238
|
+
protected disableJob(job: Job<Input, Output>): Promise<void>;
|
|
239
|
+
protected failJob(job: Job<Input, Output>, error: JobError): Promise<void>;
|
|
240
|
+
protected completeJob(job: Job<Input, Output>, output?: Output): Promise<void>;
|
|
241
|
+
/**
|
|
242
|
+
* Signals the abort of a job
|
|
243
|
+
* @param jobId The ID of the job to abort
|
|
244
|
+
*/
|
|
245
|
+
abort(jobId: unknown): Promise<void>;
|
|
246
|
+
/**
|
|
247
|
+
* Handles the abort of a job
|
|
248
|
+
* @param jobId The ID of the job to abort
|
|
249
|
+
*/
|
|
250
|
+
protected handleAbort(jobId: unknown): Promise<void>;
|
|
251
|
+
/**
|
|
252
|
+
* Processes a job and handles its lifecycle including runAttempts and error handling
|
|
253
|
+
*/
|
|
254
|
+
protected processSingleJob(job: Job<Input, Output>): Promise<void>;
|
|
255
|
+
/**
|
|
256
|
+
* Main job processing loop
|
|
257
|
+
*/
|
|
258
|
+
protected processJobs(): Promise<void>;
|
|
259
|
+
protected cleanUpJobs(): Promise<void>;
|
|
260
|
+
/**
|
|
261
|
+
* Monitors jobs that have progress listeners attached
|
|
262
|
+
* Polls for updates to jobs being processed elsewhere
|
|
263
|
+
* Only emits events when progress state has changed
|
|
264
|
+
*/
|
|
265
|
+
protected monitorJobs(): Promise<void>;
|
|
266
|
+
/**
|
|
267
|
+
* Fixes stuck jobs when the server restarts
|
|
268
|
+
*/
|
|
269
|
+
protected fixupJobs(): Promise<void>;
|
|
270
|
+
}
|
|
271
|
+
export {};
|
|
272
|
+
//# sourceMappingURL=JobQueue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JobQueue.d.ts","sourceRoot":"","sources":["../../src/job/JobQueue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { EventParameters } from "@workglow/util";
|
|
7
|
+
import { JobQueueStats } from "./JobQueue";
|
|
8
|
+
/**
|
|
9
|
+
* Events that can be emitted by the JobQueue
|
|
10
|
+
*/
|
|
11
|
+
export type JobQueueEventListeners<Input, Output> = {
|
|
12
|
+
queue_start: (queueName: string) => void;
|
|
13
|
+
queue_stop: (queueName: string) => void;
|
|
14
|
+
job_start: (queueName: string, jobId: unknown) => void;
|
|
15
|
+
job_aborting: (queueName: string, jobId: unknown) => void;
|
|
16
|
+
job_complete: (queueName: string, jobId: unknown, output: Output) => void;
|
|
17
|
+
job_error: (queueName: string, jobId: unknown, error: string) => void;
|
|
18
|
+
job_disabled: (queueName: string, jobId: unknown) => void;
|
|
19
|
+
job_retry: (queueName: string, jobId: unknown, runAfter: Date) => void;
|
|
20
|
+
queue_stats_update: (queueName: string, stats: JobQueueStats) => void;
|
|
21
|
+
job_progress: (queueName: string, jobId: unknown, progress: number, message: string, details: Record<string, any> | null) => void;
|
|
22
|
+
};
|
|
23
|
+
export type JobQueueEvents = keyof JobQueueEventListeners<any, any>;
|
|
24
|
+
export type JobQueueEventListener<Event extends JobQueueEvents> = JobQueueEventListeners<any, any>[Event];
|
|
25
|
+
export type JobQueueEventParameters<Event extends JobQueueEvents, Input, Output> = EventParameters<JobQueueEventListeners<Input, Output>, Event>;
|
|
26
|
+
/**
|
|
27
|
+
* Type for progress event listener callback
|
|
28
|
+
*/
|
|
29
|
+
export type JobProgressListener = (progress: number, message: string, details: Record<string, any> | null) => void;
|
|
30
|
+
//# sourceMappingURL=JobQueueEventListeners.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JobQueueEventListeners.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueEventListeners.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,sBAAsB,CAAC,KAAK,EAAE,MAAM,IAAI;IAClD,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvD,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1D,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtE,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1D,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC;IACvE,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACtE,YAAY,EAAE,CACZ,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KAChC,IAAI,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAEpE,MAAM,MAAM,qBAAqB,CAAC,KAAK,SAAS,cAAc,IAAI,sBAAsB,CACtF,GAAG,EACH,GAAG,CACJ,CAAC,KAAK,CAAC,CAAC;AAET,MAAM,MAAM,uBAAuB,CAAC,KAAK,SAAS,cAAc,EAAE,KAAK,EAAE,MAAM,IAAI,eAAe,CAChG,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,EACrC,KAAK,CACN,CAAC;AACF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KAChC,IAAI,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ILimiter } from "./ILimiter";
|
|
7
|
+
export declare class CompositeLimiter implements ILimiter {
|
|
8
|
+
private limiters;
|
|
9
|
+
constructor(limiters?: ILimiter[]);
|
|
10
|
+
addLimiter(limiter: ILimiter): void;
|
|
11
|
+
canProceed(): Promise<boolean>;
|
|
12
|
+
recordJobStart(): Promise<void>;
|
|
13
|
+
recordJobCompletion(): Promise<void>;
|
|
14
|
+
getNextAvailableTime(): Promise<Date>;
|
|
15
|
+
setNextAvailableTime(date: Date): Promise<void>;
|
|
16
|
+
clear(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=CompositeLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompositeLimiter.d.ts","sourceRoot":"","sources":["../../src/limiter/CompositeLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,QAAQ,GAAE,QAAQ,EAAO;IAIrC,UAAU,CAAC,OAAO,EAAE,QAAQ,GAAG,IAAI;IAI7B,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAS9B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAWrC,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ILimiter } from "./ILimiter";
|
|
7
|
+
export declare const CONCURRENT_JOB_LIMITER: import("@workglow/util").ServiceToken<ILimiter>;
|
|
8
|
+
/**
|
|
9
|
+
* Concurrency limiter that limits the number of concurrent jobs.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ConcurrencyLimiter implements ILimiter {
|
|
12
|
+
private currentRunningJobs;
|
|
13
|
+
private readonly maxConcurrentJobs;
|
|
14
|
+
private readonly timeSliceInMilliseconds;
|
|
15
|
+
private nextAllowedStartTime;
|
|
16
|
+
constructor(maxConcurrentJobs: number, timeSliceInMilliseconds?: number);
|
|
17
|
+
canProceed(): Promise<boolean>;
|
|
18
|
+
recordJobStart(): Promise<void>;
|
|
19
|
+
recordJobCompletion(): Promise<void>;
|
|
20
|
+
getNextAvailableTime(): Promise<Date>;
|
|
21
|
+
setNextAvailableTime(date: Date): Promise<void>;
|
|
22
|
+
clear(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=ConcurrencyLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConcurrencyLimiter.d.ts","sourceRoot":"","sources":["../../src/limiter/ConcurrencyLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,eAAO,MAAM,sBAAsB,iDAA8D,CAAC;AAElG;;GAEG;AACH,qBAAa,kBAAmB,YAAW,QAAQ;IACjD,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IACjD,OAAO,CAAC,oBAAoB,CAAoB;gBAEpC,iBAAiB,EAAE,MAAM,EAAE,uBAAuB,GAAE,MAAa;IAKvE,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAO9B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrC,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ILimiter } from "./ILimiter";
|
|
7
|
+
export declare class DelayLimiter implements ILimiter {
|
|
8
|
+
private delayInMilliseconds;
|
|
9
|
+
private nextAvailableTime;
|
|
10
|
+
constructor(delayInMilliseconds?: number);
|
|
11
|
+
canProceed(): Promise<boolean>;
|
|
12
|
+
recordJobStart(): Promise<void>;
|
|
13
|
+
recordJobCompletion(): Promise<void>;
|
|
14
|
+
getNextAvailableTime(): Promise<Date>;
|
|
15
|
+
setNextAvailableTime(date: Date): Promise<void>;
|
|
16
|
+
clear(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=DelayLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DelayLimiter.d.ts","sourceRoot":"","sources":["../../src/limiter/DelayLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,qBAAa,YAAa,YAAW,QAAQ;IAE/B,OAAO,CAAC,mBAAmB;IADvC,OAAO,CAAC,iBAAiB,CAAoB;gBACzB,mBAAmB,GAAE,MAAW;IAE9C,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAI9B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ILimiter, RateLimiterOptions } from "./ILimiter";
|
|
7
|
+
export declare const EVENLY_SPACED_JOB_RATE_LIMITER: import("@workglow/util").ServiceToken<ILimiter>;
|
|
8
|
+
/**
|
|
9
|
+
* Rate limiter that spreads requests evenly across a time window.
|
|
10
|
+
* Instead of allowing all requests up to the limit and then waiting,
|
|
11
|
+
* this limiter spaces out the requests evenly across the window.
|
|
12
|
+
*/
|
|
13
|
+
export declare class EvenlySpacedRateLimiter implements ILimiter {
|
|
14
|
+
private readonly maxExecutions;
|
|
15
|
+
private readonly windowSizeMs;
|
|
16
|
+
private readonly idealInterval;
|
|
17
|
+
private nextAvailableTime;
|
|
18
|
+
private lastStartTime;
|
|
19
|
+
private durations;
|
|
20
|
+
constructor({ maxExecutions, windowSizeInSeconds }: RateLimiterOptions);
|
|
21
|
+
/** Can we start a new job right now? */
|
|
22
|
+
canProceed(): Promise<boolean>;
|
|
23
|
+
/** Record that a job is starting now. */
|
|
24
|
+
recordJobStart(): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Call this when a job finishes.
|
|
27
|
+
* We measure its duration, update our running-average,
|
|
28
|
+
* and then compute how long to wait before the next job start.
|
|
29
|
+
*/
|
|
30
|
+
recordJobCompletion(): Promise<void>;
|
|
31
|
+
getNextAvailableTime(): Promise<Date>;
|
|
32
|
+
setNextAvailableTime(date: Date): Promise<void>;
|
|
33
|
+
clear(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=EvenlySpacedRateLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EvenlySpacedRateLimiter.d.ts","sourceRoot":"","sources":["../../src/limiter/EvenlySpacedRateLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE1D,eAAO,MAAM,8BAA8B,iDAE1C,CAAC;AAEF;;;;GAIG;AACH,qBAAa,uBAAwB,YAAW,QAAQ;IACtD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,iBAAiB,CAAsB;IAC/C,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,SAAS,CAAgB;gBAErB,EAAE,aAAa,EAAE,mBAAmB,EAAE,EAAE,kBAAkB;IAatE,wCAAwC;IAClC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAKpC,yCAAyC;IACnC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBrC;;;;OAIG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IASpC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
export declare const JOB_LIMITER: import("@workglow/util").ServiceToken<ILimiter>;
|
|
7
|
+
/**
|
|
8
|
+
* Interface for a job limiter.
|
|
9
|
+
*/
|
|
10
|
+
export interface ILimiter {
|
|
11
|
+
canProceed(): Promise<boolean>;
|
|
12
|
+
recordJobStart(): Promise<void>;
|
|
13
|
+
recordJobCompletion(): Promise<void>;
|
|
14
|
+
getNextAvailableTime(): Promise<Date>;
|
|
15
|
+
setNextAvailableTime(date: Date): Promise<void>;
|
|
16
|
+
clear(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export interface RateLimiterOptions {
|
|
19
|
+
readonly maxExecutions: number;
|
|
20
|
+
readonly windowSizeInSeconds: number;
|
|
21
|
+
}
|
|
22
|
+
export interface RateLimiterWithBackoffOptions extends RateLimiterOptions {
|
|
23
|
+
readonly initialBackoffDelay?: number;
|
|
24
|
+
readonly backoffMultiplier?: number;
|
|
25
|
+
readonly maxBackoffDelay?: number;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=ILimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ILimiter.d.ts","sourceRoot":"","sources":["../../src/limiter/ILimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,eAAO,MAAM,WAAW,iDAAmD,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,6BAA8B,SAAQ,kBAAkB;IACvE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ILimiter, RateLimiterWithBackoffOptions } from "./ILimiter";
|
|
7
|
+
export declare const MEMORY_JOB_RATE_LIMITER: import("@workglow/util").ServiceToken<ILimiter>;
|
|
8
|
+
/**
|
|
9
|
+
* In-memory implementation of a rate limiter.
|
|
10
|
+
* Manages request counts and delays to control job execution.
|
|
11
|
+
*/
|
|
12
|
+
export declare class InMemoryRateLimiter implements ILimiter {
|
|
13
|
+
private requests;
|
|
14
|
+
private nextAvailableTime;
|
|
15
|
+
private currentBackoffDelay;
|
|
16
|
+
private readonly maxExecutions;
|
|
17
|
+
private readonly windowSizeInMilliseconds;
|
|
18
|
+
private readonly initialBackoffDelay;
|
|
19
|
+
private readonly backoffMultiplier;
|
|
20
|
+
private readonly maxBackoffDelay;
|
|
21
|
+
constructor({ maxExecutions, windowSizeInSeconds, initialBackoffDelay, backoffMultiplier, maxBackoffDelay, }: RateLimiterWithBackoffOptions);
|
|
22
|
+
private removeOldRequests;
|
|
23
|
+
private increaseBackoff;
|
|
24
|
+
private addJitter;
|
|
25
|
+
canProceed(): Promise<boolean>;
|
|
26
|
+
recordJobStart(): Promise<void>;
|
|
27
|
+
recordJobCompletion(): Promise<void>;
|
|
28
|
+
getNextAvailableTime(): Promise<Date>;
|
|
29
|
+
setNextAvailableTime(date: Date): Promise<void>;
|
|
30
|
+
clear(): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=InMemoryRateLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InMemoryRateLimiter.d.ts","sourceRoot":"","sources":["../../src/limiter/InMemoryRateLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,QAAQ,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAErE,eAAO,MAAM,uBAAuB,iDAA+D,CAAC;AAEpG;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,QAAQ;IAClD,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,mBAAmB,CAAS;IAEpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAS;IAClD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,EACV,aAAa,EACb,mBAAmB,EACnB,mBAA2B,EAC3B,iBAAqB,EACrB,eAAyB,GAC1B,EAAE,6BAA6B;IAyBhC,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,SAAS;IAKX,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAiB9B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAW/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAKrC,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ILimiter } from "./ILimiter";
|
|
7
|
+
export declare const NULL_JOB_LIMITER: import("@workglow/util").ServiceToken<ILimiter>;
|
|
8
|
+
/**
|
|
9
|
+
* Null limiter that does nothing.
|
|
10
|
+
*/
|
|
11
|
+
export declare class NullLimiter implements ILimiter {
|
|
12
|
+
canProceed(): Promise<boolean>;
|
|
13
|
+
recordJobStart(): Promise<void>;
|
|
14
|
+
recordJobCompletion(): Promise<void>;
|
|
15
|
+
getNextAvailableTime(): Promise<Date>;
|
|
16
|
+
setNextAvailableTime(date: Date): Promise<void>;
|
|
17
|
+
clear(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=NullLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NullLimiter.d.ts","sourceRoot":"","sources":["../../src/limiter/NullLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,eAAO,MAAM,gBAAgB,iDAAwD,CAAC;AAEtF;;GAEG;AACH,qBAAa,WAAY,YAAW,QAAQ;IACpC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAI9B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ILimiter, RateLimiterWithBackoffOptions } from "@workglow/job-queue";
|
|
7
|
+
import { Pool } from "pg";
|
|
8
|
+
export declare const POSTGRES_JOB_RATE_LIMITER: import("@workglow/util").ServiceToken<ILimiter>;
|
|
9
|
+
/**
|
|
10
|
+
* PostgreSQL implementation of a rate limiter.
|
|
11
|
+
* Manages request counts and delays to control job execution.
|
|
12
|
+
*/
|
|
13
|
+
export declare class PostgresRateLimiter implements ILimiter {
|
|
14
|
+
protected readonly db: Pool;
|
|
15
|
+
private readonly queueName;
|
|
16
|
+
private readonly windowSizeInMilliseconds;
|
|
17
|
+
private currentBackoffDelay;
|
|
18
|
+
constructor(db: Pool, queueName: string, { maxExecutions, windowSizeInSeconds, initialBackoffDelay, backoffMultiplier, maxBackoffDelay, }: RateLimiterWithBackoffOptions);
|
|
19
|
+
private readonly maxExecutions;
|
|
20
|
+
private readonly initialBackoffDelay;
|
|
21
|
+
private readonly backoffMultiplier;
|
|
22
|
+
private readonly maxBackoffDelay;
|
|
23
|
+
private dbPromise;
|
|
24
|
+
private addJitter;
|
|
25
|
+
private increaseBackoff;
|
|
26
|
+
ensureTableExists(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Clears all rate limit entries for this queue.
|
|
29
|
+
*/
|
|
30
|
+
clear(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Checks if a job can proceed based on rate limiting rules.
|
|
33
|
+
* @returns True if the job can proceed, false otherwise
|
|
34
|
+
*/
|
|
35
|
+
canProceed(): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* Records a new job attempt.
|
|
38
|
+
* @returns The ID of the added job
|
|
39
|
+
*/
|
|
40
|
+
recordJobStart(): Promise<void>;
|
|
41
|
+
recordJobCompletion(): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves the next available time for the specific queue.
|
|
44
|
+
* @returns The next available time
|
|
45
|
+
*/
|
|
46
|
+
getNextAvailableTime(): Promise<Date>;
|
|
47
|
+
/**
|
|
48
|
+
* Sets the next available time for the specific queue.
|
|
49
|
+
* @param date - The new next available time
|
|
50
|
+
*/
|
|
51
|
+
setNextAvailableTime(date: Date): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=PostgresRateLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostgresRateLimiter.d.ts","sourceRoot":"","sources":["../../src/limiter/PostgresRateLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE1B,eAAO,MAAM,yBAAyB,iDAErC,CAAC;AAEF;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,QAAQ;IAKhD,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL5B,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAS;IAClD,OAAO,CAAC,mBAAmB,CAAS;gBAGf,EAAE,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EAClC,EACE,aAAa,EACb,mBAAmB,EACnB,mBAA2B,EAC3B,iBAAqB,EACrB,eAAyB,GAC1B,EAAE,6BAA6B;IA2BlC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,SAAS,CAAgB;IAEjC,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,eAAe;IAOV,iBAAiB;IAgB9B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5B;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IA0CpC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI1C;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAyC3C;;;OAGG;IACG,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAatD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ILimiter, RateLimiterWithBackoffOptions } from "@workglow/job-queue";
|
|
7
|
+
import type { Sqlite } from "@workglow/sqlite";
|
|
8
|
+
export declare const SQLITE_JOB_RATE_LIMITER: import("@workglow/util").ServiceToken<ILimiter>;
|
|
9
|
+
/**
|
|
10
|
+
* SQLite implementation of a rate limiter.
|
|
11
|
+
* Manages request counts and delays to control job execution.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SqliteRateLimiter implements ILimiter {
|
|
14
|
+
private readonly db;
|
|
15
|
+
private readonly queueName;
|
|
16
|
+
private readonly windowSizeInMilliseconds;
|
|
17
|
+
private currentBackoffDelay;
|
|
18
|
+
constructor(db: Sqlite.Database, queueName: string, { maxExecutions, windowSizeInSeconds, initialBackoffDelay, backoffMultiplier, maxBackoffDelay, }: RateLimiterWithBackoffOptions);
|
|
19
|
+
private readonly maxExecutions;
|
|
20
|
+
private readonly initialBackoffDelay;
|
|
21
|
+
private readonly backoffMultiplier;
|
|
22
|
+
private readonly maxBackoffDelay;
|
|
23
|
+
private addJitter;
|
|
24
|
+
private increaseBackoff;
|
|
25
|
+
ensureTableExists(): this;
|
|
26
|
+
/**
|
|
27
|
+
* Clears all rate limit entries for this queue.
|
|
28
|
+
*/
|
|
29
|
+
clear(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Checks if a job can proceed based on rate limiting rules.
|
|
32
|
+
* @returns True if the job can proceed, false otherwise
|
|
33
|
+
*/
|
|
34
|
+
canProceed(): Promise<boolean>;
|
|
35
|
+
/**
|
|
36
|
+
* Records a new job attempt.
|
|
37
|
+
* @returns The ID of the added job
|
|
38
|
+
*/
|
|
39
|
+
recordJobStart(): Promise<void>;
|
|
40
|
+
recordJobCompletion(): Promise<void>;
|
|
41
|
+
getNextAvailableTime(): Promise<Date>;
|
|
42
|
+
setNextAvailableTime(date: Date): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=SqliteRateLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqliteRateLimiter.d.ts","sourceRoot":"","sources":["../../src/limiter/SqliteRateLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG/C,eAAO,MAAM,uBAAuB,iDAA+D,CAAC;AAEpG;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,QAAQ;IAChD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAkB;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAS;IAClD,OAAO,CAAC,mBAAmB,CAAS;gBAGlC,EAAE,EAAE,MAAM,CAAC,QAAQ,EACnB,SAAS,EAAE,MAAM,EACjB,EACE,aAAa,EACb,mBAAmB,EACnB,mBAA2B,EAC3B,iBAAqB,EACrB,eAAyB,GAC1B,EAAE,6BAA6B;IA6BlC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,eAAe;IAOhB,iBAAiB;IAiBxB;;OAEG;IACG,KAAK;IASX;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAqCpC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCrC,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAWtD"}
|