@stacksjs/queue 0.70.23 → 0.70.25
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/index.js +30 -4912
- package/dist/src/action.d.ts +46 -0
- package/dist/src/batch.d.ts +115 -0
- package/dist/src/discovery.d.ts +79 -0
- package/dist/src/events.d.ts +138 -0
- package/dist/src/health.d.ts +85 -0
- package/dist/src/index.d.ts +137 -0
- package/dist/src/job-progress.d.ts +53 -0
- package/dist/src/job.d.ts +116 -0
- package/dist/src/notifications.d.ts +70 -0
- package/dist/src/scheduler.d.ts +52 -0
- package/dist/src/testing.d.ts +74 -0
- package/dist/src/worker.d.ts +26 -0
- package/package.json +19 -7
- package/dist/action.d.ts +0 -25
- package/dist/index.d.ts +0 -3
- package/dist/job.d.ts +0 -199
- package/dist/process.d.ts +0 -24
- package/dist/utils.d.ts +0 -4
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a job builder for dispatching file-based jobs
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* // Basic dispatch
|
|
7
|
+
* await job('SendWelcomeEmail', { userId: 1 }).dispatch()
|
|
8
|
+
*
|
|
9
|
+
* // With options
|
|
10
|
+
* await job('ProcessOrder', { orderId: 123 })
|
|
11
|
+
* .onQueue('orders')
|
|
12
|
+
* .tries(3)
|
|
13
|
+
* .backoff([10, 30, 60])
|
|
14
|
+
* .dispatch()
|
|
15
|
+
*
|
|
16
|
+
* // Immediate execution
|
|
17
|
+
* await job('SendNotification', { message: 'Hello' }).dispatchNow()
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function job(name: string, payload?: any): JobBuilder;
|
|
21
|
+
/**
|
|
22
|
+
* Create a job batch for dispatching multiple jobs together
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import SendWelcomeEmail from '~/app/Jobs/SendWelcomeEmail'
|
|
27
|
+
* import ProcessOrder from '~/app/Jobs/ProcessOrder'
|
|
28
|
+
*
|
|
29
|
+
* const batch = await jobBatch([
|
|
30
|
+
* { job: SendWelcomeEmail, payload: { email: 'user@example.com' } },
|
|
31
|
+
* { job: ProcessOrder, payload: { orderId: 123 } },
|
|
32
|
+
* ])
|
|
33
|
+
* .name('Onboard User')
|
|
34
|
+
* .allowFailures()
|
|
35
|
+
* .then(async (_b) => console.log('All done!'))
|
|
36
|
+
* .dispatch()
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function jobBatch(jobs: Array<import('./action').Job | import('./batch').BatchableJob>): import('./batch').PendingBatch;
|
|
40
|
+
/**
|
|
41
|
+
* Run a job immediately by name
|
|
42
|
+
*
|
|
43
|
+
* This loads the job from app/Jobs/{name}.ts and executes it
|
|
44
|
+
*
|
|
45
|
+
* Wraps execution in `withTraceId(...)` so log lines, db queries, and
|
|
46
|
+
* downstream HTTP calls emitted from inside the job carry the same
|
|
47
|
+
* trace id as the request (or a fresh one for cron-triggered runs).
|
|
48
|
+
* `options.traceId` lets dispatchers attach a parent id explicitly;
|
|
49
|
+
* absent that, we mint one of the form `job:<name>:<random>` so
|
|
50
|
+
* background work is at least correlatable to itself.
|
|
51
|
+
*/
|
|
52
|
+
export declare function runJob(name: string, options?: { payload?: any; context?: any; traceId?: string }): Promise<void>;
|
|
53
|
+
/*.ts`; this `Jobs` facade is the *call-site* form for
|
|
54
|
+
* dispatching by name from anywhere in the app. It lets one-liner
|
|
55
|
+
* dispatches skip the builder while still allowing the chainable form
|
|
56
|
+
* via `Jobs.make(...)` for option-heavy cases.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* // One-shot dispatch (no options)
|
|
61
|
+
* await Jobs.dispatch('SendWelcomeEmail', { userId: 1 })
|
|
62
|
+
*
|
|
63
|
+
* // Conditional dispatch
|
|
64
|
+
* await Jobs.dispatchIf(user.isNew, 'SendWelcomeEmail', { userId: user.id })
|
|
65
|
+
*
|
|
66
|
+
* // With options — fall back to the builder
|
|
67
|
+
* await Jobs.make('ProcessOrder', { orderId: 123 })
|
|
68
|
+
* .onQueue('orders')
|
|
69
|
+
* .tries(3)
|
|
70
|
+
* .dispatch()
|
|
71
|
+
*
|
|
72
|
+
* // Immediate (synchronous) execution, ignoring the queue
|
|
73
|
+
* await Jobs.dispatchNow('SendNotification', { message: 'Hello' })
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare const Jobs: {
|
|
77
|
+
/** Construct a builder without dispatching — for chained option calls. */
|
|
78
|
+
make: (name: string, payload?: any) => JobBuilder;
|
|
79
|
+
/** Dispatch a job in one call. Equivalent to `job(name, payload).dispatch()`. */
|
|
80
|
+
async dispatch: (name: string, payload?: any) => Promise<void>;
|
|
81
|
+
/** Dispatch only if `condition` is truthy. */
|
|
82
|
+
async dispatchIf: (condition: boolean, name: string, payload?: any) => Promise<void>;
|
|
83
|
+
/** Dispatch unless `condition` is truthy. */
|
|
84
|
+
async dispatchUnless: (condition: boolean, name: string, payload?: any) => Promise<void>;
|
|
85
|
+
/** Run the job synchronously, bypassing the queue. */
|
|
86
|
+
async dispatchNow: (name: string, payload?: any) => Promise<void>;
|
|
87
|
+
/** Schedule the job to run after `seconds` of delay. */
|
|
88
|
+
dispatchAfter: (seconds: number, name: string, payload?: any) => JobBuilder
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Options for job dispatch
|
|
92
|
+
*/
|
|
93
|
+
export declare interface JobDispatchOptions {
|
|
94
|
+
queue?: string
|
|
95
|
+
delay?: number
|
|
96
|
+
tries?: number
|
|
97
|
+
timeout?: number
|
|
98
|
+
backoff?: number[]
|
|
99
|
+
context?: any
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Fluent job builder for file-based jobs
|
|
103
|
+
*/
|
|
104
|
+
declare class JobBuilder {
|
|
105
|
+
constructor(name: string, payload?: any);
|
|
106
|
+
onQueue(queue: string): this;
|
|
107
|
+
delay(seconds: number): this;
|
|
108
|
+
tries(count: number): this;
|
|
109
|
+
timeout(seconds: number): this;
|
|
110
|
+
backoff(delays: number[]): this;
|
|
111
|
+
withContext(context: any): this;
|
|
112
|
+
dispatch(): Promise<void>;
|
|
113
|
+
dispatchIf(condition: boolean): Promise<void>;
|
|
114
|
+
dispatchUnless(condition: boolean): Promise<void>;
|
|
115
|
+
dispatchNow(): Promise<void>;
|
|
116
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { log } from '@stacksjs/logging';
|
|
2
|
+
/**
|
|
3
|
+
* Configure failed job notifications
|
|
4
|
+
*/
|
|
5
|
+
export declare function configureFailedJobNotifications(config: FailedJobNotificationConfig): FailedJobNotifier;
|
|
6
|
+
/**
|
|
7
|
+
* Get the global notifier
|
|
8
|
+
*/
|
|
9
|
+
export declare function getFailedJobNotifier(): FailedJobNotifier | null;
|
|
10
|
+
/**
|
|
11
|
+
* Notify about a failed job using the global notifier
|
|
12
|
+
*/
|
|
13
|
+
export declare function notifyJobFailed(job: FailedJobInfo): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Failed job info
|
|
16
|
+
*/
|
|
17
|
+
export declare interface FailedJobInfo {
|
|
18
|
+
id: string | number
|
|
19
|
+
name: string
|
|
20
|
+
queue: string
|
|
21
|
+
payload: any
|
|
22
|
+
exception: string
|
|
23
|
+
failedAt: Date
|
|
24
|
+
attempts: number
|
|
25
|
+
maxAttempts: number
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Notification configuration
|
|
29
|
+
*/
|
|
30
|
+
export declare interface FailedJobNotificationConfig {
|
|
31
|
+
channels: NotificationChannel[]
|
|
32
|
+
email?: {
|
|
33
|
+
to: string | string[]
|
|
34
|
+
from?: string
|
|
35
|
+
subject?: string
|
|
36
|
+
}
|
|
37
|
+
slack?: {
|
|
38
|
+
webhookUrl: string
|
|
39
|
+
channel?: string
|
|
40
|
+
username?: string
|
|
41
|
+
iconEmoji?: string
|
|
42
|
+
}
|
|
43
|
+
discord?: {
|
|
44
|
+
webhookUrl: string
|
|
45
|
+
username?: string
|
|
46
|
+
avatarUrl?: string
|
|
47
|
+
}
|
|
48
|
+
webhook?: {
|
|
49
|
+
url: string
|
|
50
|
+
headers?: Record<string, string>
|
|
51
|
+
secret?: string
|
|
52
|
+
}
|
|
53
|
+
rateLimit?: number
|
|
54
|
+
batch?: boolean
|
|
55
|
+
batchInterval?: number
|
|
56
|
+
filter?: (job: FailedJobInfo) => boolean
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Notification channel types
|
|
60
|
+
*/
|
|
61
|
+
export type NotificationChannel = 'email' | 'slack' | 'discord' | 'webhook' | 'log';
|
|
62
|
+
/**
|
|
63
|
+
* Failed job notification manager
|
|
64
|
+
*/
|
|
65
|
+
export declare class FailedJobNotifier {
|
|
66
|
+
constructor(config: FailedJobNotificationConfig);
|
|
67
|
+
notify(job: FailedJobInfo): Promise<void>;
|
|
68
|
+
shutdown(): Promise<void>;
|
|
69
|
+
cleanup(): Promise<void>;
|
|
70
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type DiscoveredJob } from './discovery';
|
|
2
|
+
/**
|
|
3
|
+
* Start the scheduler
|
|
4
|
+
*/
|
|
5
|
+
export declare function startScheduler(config?: Partial<SchedulerConfig>): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Stop the scheduler
|
|
8
|
+
*/
|
|
9
|
+
export declare function stopScheduler(): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Get scheduler status
|
|
12
|
+
*/
|
|
13
|
+
export declare function getSchedulerStatus(): {
|
|
14
|
+
isRunning: boolean
|
|
15
|
+
jobCount: number
|
|
16
|
+
jobs: Array<{
|
|
17
|
+
name: string
|
|
18
|
+
schedule: string | undefined
|
|
19
|
+
lastRun: Date | null
|
|
20
|
+
nextRun: Date | null
|
|
21
|
+
isRunning: boolean
|
|
22
|
+
}>
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Check if scheduler is running
|
|
26
|
+
*/
|
|
27
|
+
export declare function isSchedulerRunning(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Get registered scheduled jobs
|
|
30
|
+
*/
|
|
31
|
+
export declare function getRegisteredJobs(): Map<string, ScheduledJobState>;
|
|
32
|
+
/**
|
|
33
|
+
* Manually trigger a scheduled job
|
|
34
|
+
*/
|
|
35
|
+
export declare function triggerJob(name: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Scheduler configuration
|
|
38
|
+
*/
|
|
39
|
+
declare interface SchedulerConfig {
|
|
40
|
+
checkInterval: number
|
|
41
|
+
timezone?: string
|
|
42
|
+
preventOverlapping: boolean
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Scheduled job state
|
|
46
|
+
*/
|
|
47
|
+
declare interface ScheduledJobState {
|
|
48
|
+
job: DiscoveredJob
|
|
49
|
+
lastRun: Date | null
|
|
50
|
+
nextRun: Date | null
|
|
51
|
+
isRunning: boolean
|
|
52
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { JobOptions } from '@stacksjs/types';
|
|
2
|
+
/**
|
|
3
|
+
* Enable fake queue for testing
|
|
4
|
+
*/
|
|
5
|
+
export declare function fake(): FakeQueue;
|
|
6
|
+
/**
|
|
7
|
+
* Get the fake queue instance
|
|
8
|
+
*/
|
|
9
|
+
export declare function getFakeQueue(): FakeQueue | null;
|
|
10
|
+
/**
|
|
11
|
+
* Check if queue is faked
|
|
12
|
+
*/
|
|
13
|
+
export declare function isFaked(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Restore real queue behavior
|
|
16
|
+
*/
|
|
17
|
+
export declare function restore(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Create a queue tester instance
|
|
20
|
+
*/
|
|
21
|
+
export declare function createQueueTester(): QueueTester;
|
|
22
|
+
/**
|
|
23
|
+
* Test helper to run a job synchronously
|
|
24
|
+
*/
|
|
25
|
+
export declare function runJob<T, R>(jobModule: { handle: (data: T) => Promise<R> | R }, data: T): Promise<R>;
|
|
26
|
+
/**
|
|
27
|
+
* Test helper to expect a job to fail
|
|
28
|
+
*/
|
|
29
|
+
export declare function expectJobToFail<T>(jobModule: { handle: (data: T) => Promise<any> }, data: T, expectedError?: string | RegExp): Promise<Error>;
|
|
30
|
+
/**
|
|
31
|
+
* Dispatched job record for assertions
|
|
32
|
+
*/
|
|
33
|
+
export declare interface DispatchedJob<T = any> {
|
|
34
|
+
name: string
|
|
35
|
+
data: T
|
|
36
|
+
options: Partial<JobOptions>
|
|
37
|
+
dispatchedAt: Date
|
|
38
|
+
queue: string
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fake queue for testing
|
|
42
|
+
*/
|
|
43
|
+
declare class FakeQueue {
|
|
44
|
+
dispatch<T>(name: string, data: T, options?: Partial<JobOptions>): void;
|
|
45
|
+
push<T>(name: string, data: T, options?: Partial<JobOptions>): void;
|
|
46
|
+
dispatched(name?: string): DispatchedJob[];
|
|
47
|
+
pushed(name?: string): DispatchedJob[];
|
|
48
|
+
assertDispatched(name: string, callback?: (job: DispatchedJob) => boolean): void;
|
|
49
|
+
assertNotDispatched(name: string): void;
|
|
50
|
+
assertDispatchedTimes(name: string, times: number): void;
|
|
51
|
+
assertNothingDispatched(): void;
|
|
52
|
+
assertPushed(name: string, callback?: (job: DispatchedJob) => boolean): void;
|
|
53
|
+
assertPushedWithDelay(name: string, delay: number): void;
|
|
54
|
+
assertPushedOn(queue: string, name: string): void;
|
|
55
|
+
processJob<T>(name: string, handler: (data: T) => Promise<any>): Promise<void>;
|
|
56
|
+
processed(name?: string): DispatchedJob[];
|
|
57
|
+
failed(name?: string): Array<{ job: DispatchedJob, error: Error }>;
|
|
58
|
+
reset(): void;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Queue testing helper class
|
|
62
|
+
*/
|
|
63
|
+
export declare class QueueTester {
|
|
64
|
+
constructor();
|
|
65
|
+
dispatch<T>(name: string, data: T, options?: Partial<JobOptions>): this;
|
|
66
|
+
push<T>(name: string, data: T, options?: Partial<JobOptions>): this;
|
|
67
|
+
assertDispatched(name: string, callback?: (job: DispatchedJob) => boolean): this;
|
|
68
|
+
assertNotDispatched(name: string): this;
|
|
69
|
+
assertDispatchedTimes(name: string, times: number): this;
|
|
70
|
+
assertNothingDispatched(): this;
|
|
71
|
+
dispatched(name?: string): DispatchedJob[];
|
|
72
|
+
reset(): this;
|
|
73
|
+
cleanup(): void;
|
|
74
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Result } from '@stacksjs/error-handling';
|
|
2
|
+
/**
|
|
3
|
+
* Start the queue processor (worker)
|
|
4
|
+
* This is the main function called by `buddy queue:work`
|
|
5
|
+
*/
|
|
6
|
+
export declare function startProcessor(queueName?: string, options?: { concurrency?: number }): Promise<Result<undefined, Error>>;
|
|
7
|
+
/**
|
|
8
|
+
* Stop the queue processor
|
|
9
|
+
*/
|
|
10
|
+
export declare function stopProcessor(): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Retry all failed jobs
|
|
13
|
+
*/
|
|
14
|
+
export declare function executeFailedJobs(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Retry a specific failed job
|
|
17
|
+
*/
|
|
18
|
+
export declare function retryFailedJob(id: number): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the count of currently active (processing) jobs
|
|
21
|
+
*/
|
|
22
|
+
export declare function getActiveJobCount(): number;
|
|
23
|
+
/**
|
|
24
|
+
* Check if the worker is currently running
|
|
25
|
+
*/
|
|
26
|
+
export declare function isWorkerRunning(): boolean;
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/queue",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.70.
|
|
5
|
-
"description": "The Stacks Queue system.",
|
|
4
|
+
"version": "0.70.25",
|
|
5
|
+
"description": "The Stacks Queue system powered by bun-queue.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
|
-
"contributors": [
|
|
7
|
+
"contributors": [
|
|
8
|
+
"Chris Breuer <chris@stacksjs.com>"
|
|
9
|
+
],
|
|
8
10
|
"license": "MIT",
|
|
9
11
|
"funding": "https://github.com/sponsors/chrisbbreuer",
|
|
10
12
|
"homepage": "https://github.com/stacksjs/stacks/tree/main/storage/framework/core/queue#readme",
|
|
@@ -18,9 +20,10 @@
|
|
|
18
20
|
},
|
|
19
21
|
"keywords": [
|
|
20
22
|
"queue",
|
|
21
|
-
"
|
|
23
|
+
"bun-queue",
|
|
22
24
|
"redis",
|
|
23
|
-
"
|
|
25
|
+
"job",
|
|
26
|
+
"worker",
|
|
24
27
|
"stacks",
|
|
25
28
|
"framework",
|
|
26
29
|
"typescript",
|
|
@@ -28,21 +31,30 @@
|
|
|
28
31
|
],
|
|
29
32
|
"exports": {
|
|
30
33
|
".": {
|
|
34
|
+
"bun": "./src/index.ts",
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
31
36
|
"import": "./dist/index.js"
|
|
32
37
|
},
|
|
33
38
|
"./*": {
|
|
39
|
+
"bun": "./src/*",
|
|
34
40
|
"import": "./dist/*"
|
|
35
41
|
}
|
|
36
42
|
},
|
|
37
43
|
"module": "dist/index.js",
|
|
38
44
|
"types": "dist/index.d.ts",
|
|
39
|
-
"files": [
|
|
45
|
+
"files": [
|
|
46
|
+
"README.md",
|
|
47
|
+
"dist"
|
|
48
|
+
],
|
|
40
49
|
"scripts": {
|
|
41
50
|
"build": "bun build.ts",
|
|
42
51
|
"typecheck": "bun tsc --noEmit",
|
|
43
52
|
"prepublishOnly": "bun run build"
|
|
44
53
|
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@stacksjs/bun-queue": "^0.1.0"
|
|
56
|
+
},
|
|
45
57
|
"devDependencies": {
|
|
46
|
-
"
|
|
58
|
+
"better-dx": "^0.2.12"
|
|
47
59
|
}
|
|
48
60
|
}
|
package/dist/action.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { JobOptions } from '@stacksjs/types';
|
|
2
|
-
|
|
3
|
-
export declare class Job {
|
|
4
|
-
name: JobOptions['name']
|
|
5
|
-
description: JobOptions['description']
|
|
6
|
-
action?: JobOptions['action']
|
|
7
|
-
handle?: JobOptions['handle']
|
|
8
|
-
rate: JobOptions['rate']
|
|
9
|
-
tries: JobOptions['tries']
|
|
10
|
-
backoff: JobOptions['backoff']
|
|
11
|
-
backoffConfig: JobOptions['backoffConfig']
|
|
12
|
-
enabled: JobOptions['enabled']
|
|
13
|
-
|
|
14
|
-
constructor({ name, description, handle, rate, tries, backoff, backoffConfig, action, enabled }: JobOptions) {
|
|
15
|
-
this.name = name
|
|
16
|
-
this.description = description
|
|
17
|
-
this.handle = handle
|
|
18
|
-
this.rate = rate
|
|
19
|
-
this.action = action
|
|
20
|
-
this.tries = tries
|
|
21
|
-
this.backoff = backoff
|
|
22
|
-
this.backoffConfig = backoffConfig
|
|
23
|
-
this.enabled = enabled
|
|
24
|
-
}
|
|
25
|
-
}
|
package/dist/index.d.ts
DELETED
package/dist/job.d.ts
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import type { QueueOption } from '@stacksjs/types';
|
|
2
|
-
|
|
3
|
-
declare const queueDriver: 'database';
|
|
4
|
-
declare interface JobConfig {
|
|
5
|
-
handle?: (payload?: any) => Promise<void>
|
|
6
|
-
action?: string | (() => Promise<void>)
|
|
7
|
-
}
|
|
8
|
-
declare interface Dispatchable {
|
|
9
|
-
dispatch: () => Promise<void>
|
|
10
|
-
dispatchNow: () => Promise<void>
|
|
11
|
-
delay: (seconds: number) => this
|
|
12
|
-
afterResponse: () => this
|
|
13
|
-
chain: (jobs: Dispatchable[]) => this
|
|
14
|
-
onQueue: (queue: string) => this
|
|
15
|
-
}
|
|
16
|
-
export declare function runJob(name: string, options: QueueOption): Promise<void>;
|
|
17
|
-
export declare class Queue implements Dispatchable {
|
|
18
|
-
protected options: QueueOption = {}
|
|
19
|
-
|
|
20
|
-
constructor(
|
|
21
|
-
protected name: string,
|
|
22
|
-
protected payload?: any,
|
|
23
|
-
) { }
|
|
24
|
-
|
|
25
|
-
async dispatch(): Promise<void> {
|
|
26
|
-
const queueName = this.options.queue || 'default'
|
|
27
|
-
|
|
28
|
-
const jobPayload = this.createJobPayload(queueName)
|
|
29
|
-
|
|
30
|
-
if (this.isQueuedDriver()) {
|
|
31
|
-
await this.storeQueuedJob(jobPayload)
|
|
32
|
-
return
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (this.options.afterResponse) {
|
|
36
|
-
this.deferAfterResponse()
|
|
37
|
-
return
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (this.options.delay) {
|
|
41
|
-
this.deferWithDelay()
|
|
42
|
-
return
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
await this.runJobImmediately(jobPayload)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private isQueuedDriver(): boolean {
|
|
49
|
-
return ['database', 'redis'].includes(queueDriver)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
private createJobPayload(queueName: string): QueueOption {
|
|
53
|
-
return {
|
|
54
|
-
queue: queueName,
|
|
55
|
-
payload: this.payload,
|
|
56
|
-
context: this.options.context,
|
|
57
|
-
maxTries: this.options.maxTries,
|
|
58
|
-
timeout: this.options.timeout,
|
|
59
|
-
backoff: this.options.backoff,
|
|
60
|
-
delay: this.options.delay,
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
private async storeQueuedJob(jobPayload: any): Promise<void> {
|
|
65
|
-
await storeJob(this.name, jobPayload)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
private deferAfterResponse(): void {
|
|
69
|
-
process.on('beforeExit', async () => {
|
|
70
|
-
await this.dispatchNow()
|
|
71
|
-
})
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
private deferWithDelay(): void {
|
|
75
|
-
setTimeout(async () => {
|
|
76
|
-
await this.dispatchNow()
|
|
77
|
-
}, this.options.delay || 0)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
private async runJobImmediately(jobPayload: any): Promise<void> {
|
|
81
|
-
try {
|
|
82
|
-
await runJob(this.name, jobPayload)
|
|
83
|
-
await this.runChainedJobs()
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
log.error(`Failed to dispatch job ${this.name}:`, error)
|
|
87
|
-
throw error
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
private async runChainedJobs(): Promise<void> {
|
|
92
|
-
if (!this.options.chainedJobs?.length)
|
|
93
|
-
return
|
|
94
|
-
|
|
95
|
-
for (const job of this.options.chainedJobs) {
|
|
96
|
-
await job.dispatch()
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async dispatchNow(): Promise<void> {
|
|
101
|
-
try {
|
|
102
|
-
await runJob(this.name, {
|
|
103
|
-
payload: this.payload,
|
|
104
|
-
context: this.options.context,
|
|
105
|
-
immediate: true,
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
if (this.options.chainedJobs?.length) {
|
|
109
|
-
for (const job of this.options.chainedJobs) {
|
|
110
|
-
await job.dispatchNow()
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
log.error(`Failed to execute job ${this.name}:`, error)
|
|
116
|
-
throw error
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
delay(seconds: number): this {
|
|
121
|
-
this.options.delay = seconds
|
|
122
|
-
return this
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
onQueue(queue: string): this {
|
|
126
|
-
this.options.queue = queue
|
|
127
|
-
return this
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
chain(jobs: Dispatchable[]): this {
|
|
131
|
-
this.options.chainedJobs = jobs
|
|
132
|
-
return this
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
afterResponse(): this {
|
|
136
|
-
this.options.afterResponse = true
|
|
137
|
-
return this
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
tries(count: number): this {
|
|
141
|
-
this.options.maxTries = count
|
|
142
|
-
return this
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
timeout(seconds: number): this {
|
|
146
|
-
this.options.timeout = seconds
|
|
147
|
-
return this
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
backoff(attempts: number[]): this {
|
|
151
|
-
this.options.backoff = attempts
|
|
152
|
-
return this
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
withContext(context: any): this {
|
|
156
|
-
this.options.context = context
|
|
157
|
-
return this
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
export declare class JobFactory {
|
|
161
|
-
static make(name: string, payload?: any): Queue {
|
|
162
|
-
return new Queue(name, payload)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
static dispatch(name: string, payload?: any): Queue {
|
|
166
|
-
const job = new Queue(name, payload)
|
|
167
|
-
job.dispatch()
|
|
168
|
-
return job
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
static async dispatchNow(name: string, payload?: any): Promise<void> {
|
|
172
|
-
await new Queue(name, payload).dispatchNow()
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
static later(delay: number, name: string, payload?: any): Queue {
|
|
176
|
-
return new Queue(name, payload).delay(delay)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
static chain(jobs: Queue[]): Queue {
|
|
180
|
-
const firstJob = jobs[0]
|
|
181
|
-
return firstJob.chain(jobs.slice(1))
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
export declare function job(name: string, payload?: any): Queue;
|
|
185
|
-
export declare function processOrder(payload, context): void;
|
|
186
|
-
|
|
187
|
-
export default {
|
|
188
|
-
async handle() {
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
export default {
|
|
192
|
-
action: 'SendWelcomeEmail'
|
|
193
|
-
};
|
|
194
|
-
export default {
|
|
195
|
-
action: async () => {
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
export default async function(payload, context) {
|
|
199
|
-
};
|
package/dist/process.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { JitterConfig, JobOptions } from '@stacksjs/types';
|
|
2
|
-
import type { JobModel } from '../../../orm/src/models/Job';
|
|
3
|
-
|
|
4
|
-
declare interface QueuePayload {
|
|
5
|
-
path: string
|
|
6
|
-
name: string
|
|
7
|
-
maxTries: number
|
|
8
|
-
timeOut: number | null
|
|
9
|
-
timeOutAt: Date | null
|
|
10
|
-
params: any
|
|
11
|
-
classPayload: string
|
|
12
|
-
}
|
|
13
|
-
export declare function processJobs(queue: string | undefined): Promise<Ok<string, never>>;
|
|
14
|
-
export declare function executeFailedJobs(): Promise<void>;
|
|
15
|
-
export declare function retryFailedJob(id: number): Promise<void>;
|
|
16
|
-
declare function executeJobs(queue: string | undefined): Promise<void>;
|
|
17
|
-
declare function enforceMaxDelay(maxDelay: number | undefined, delay: number): number;
|
|
18
|
-
declare function addDelay(timestamp: number | undefined, currentAttempts: number, classPayload: JobOptions): number;
|
|
19
|
-
declare function meilisecondsToSeconds(meiliseconds: number): number;
|
|
20
|
-
declare function applyJitter(delay: number, jitterConfig: JitterConfig): number;
|
|
21
|
-
declare function storeFailedJob(job: JobModel, exception: string): void;
|
|
22
|
-
declare function now(): string;
|
|
23
|
-
declare function updateJobAttempts(job: JobModel, currentAttempts: number, delay: number | null): Promise<void>;
|
|
24
|
-
declare function timestampNow(): number;
|
package/dist/utils.d.ts
DELETED