@veloxts/queue 0.6.86 → 0.6.88
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/GUIDE.md +109 -14
- package/package.json +6 -5
package/GUIDE.md
CHANGED
|
@@ -1,27 +1,46 @@
|
|
|
1
1
|
# @veloxts/queue Guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Background job processing for VeloxTS applications with support for sync execution (development) and BullMQ/Redis (production).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @veloxts/queue
|
|
9
|
+
|
|
10
|
+
# For BullMQ (production)
|
|
11
|
+
pnpm add bullmq ioredis
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
### Development (Sync)
|
|
17
|
+
|
|
18
|
+
Jobs execute immediately in-process:
|
|
8
19
|
|
|
9
20
|
```typescript
|
|
21
|
+
import { veloxApp } from '@veloxts/core';
|
|
10
22
|
import { queuePlugin } from '@veloxts/queue';
|
|
11
23
|
|
|
12
|
-
app
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
### BullMQ Driver
|
|
24
|
+
const app = veloxApp();
|
|
16
25
|
|
|
17
|
-
|
|
26
|
+
app.register(queuePlugin({
|
|
27
|
+
driver: 'sync',
|
|
28
|
+
}));
|
|
18
29
|
|
|
19
|
-
|
|
20
|
-
npm install bullmq ioredis
|
|
30
|
+
await app.start();
|
|
21
31
|
```
|
|
22
32
|
|
|
33
|
+
### Production (BullMQ)
|
|
34
|
+
|
|
35
|
+
Jobs are queued in Redis and processed by workers:
|
|
36
|
+
|
|
23
37
|
```typescript
|
|
24
|
-
|
|
38
|
+
import { veloxApp } from '@veloxts/core';
|
|
39
|
+
import { queuePlugin } from '@veloxts/queue';
|
|
40
|
+
|
|
41
|
+
const app = veloxApp();
|
|
42
|
+
|
|
43
|
+
app.register(queuePlugin({
|
|
25
44
|
driver: 'bullmq',
|
|
26
45
|
config: {
|
|
27
46
|
url: process.env.REDIS_URL,
|
|
@@ -29,6 +48,15 @@ app.use(queuePlugin({
|
|
|
29
48
|
defaultConcurrency: 5,
|
|
30
49
|
},
|
|
31
50
|
}));
|
|
51
|
+
|
|
52
|
+
await app.start();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Environment Variables:**
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# .env
|
|
59
|
+
REDIS_URL=redis://user:password@your-redis-host:6379
|
|
32
60
|
```
|
|
33
61
|
|
|
34
62
|
## Defining Jobs
|
|
@@ -43,9 +71,12 @@ export const sendWelcomeEmail = defineJob({
|
|
|
43
71
|
userId: z.string().uuid(),
|
|
44
72
|
email: z.string().email(),
|
|
45
73
|
}),
|
|
46
|
-
handler: async ({ data, ctx }) => {
|
|
74
|
+
handler: async ({ data, ctx, progress }) => {
|
|
75
|
+
await progress(10);
|
|
47
76
|
const user = await ctx.db.user.findUnique({ where: { id: data.userId } });
|
|
77
|
+
await progress(50);
|
|
48
78
|
await ctx.mail.send(WelcomeEmail, { to: data.email, data: { user } });
|
|
79
|
+
await progress(100);
|
|
49
80
|
},
|
|
50
81
|
options: {
|
|
51
82
|
attempts: 3,
|
|
@@ -58,11 +89,17 @@ export const sendWelcomeEmail = defineJob({
|
|
|
58
89
|
|
|
59
90
|
```typescript
|
|
60
91
|
// Dispatch immediately
|
|
61
|
-
await ctx.queue.dispatch(sendWelcomeEmail, {
|
|
92
|
+
await ctx.queue.dispatch(sendWelcomeEmail, {
|
|
93
|
+
userId: '123',
|
|
94
|
+
email: 'user@example.com',
|
|
95
|
+
});
|
|
62
96
|
|
|
63
97
|
// Dispatch with delay
|
|
64
98
|
await ctx.queue.dispatch(sendWelcomeEmail, data, { delay: '10m' });
|
|
65
99
|
|
|
100
|
+
// Dispatch with priority (lower = higher priority)
|
|
101
|
+
await ctx.queue.dispatch(sendWelcomeEmail, data, { priority: 1 });
|
|
102
|
+
|
|
66
103
|
// Dispatch in batch
|
|
67
104
|
await ctx.queue.dispatchBatch(sendWelcomeEmail, [
|
|
68
105
|
{ userId: '1', email: 'a@example.com' },
|
|
@@ -75,6 +112,7 @@ await ctx.queue.dispatchBatch(sendWelcomeEmail, [
|
|
|
75
112
|
```typescript
|
|
76
113
|
defineJob({
|
|
77
114
|
name: 'my.job',
|
|
115
|
+
schema: MySchema,
|
|
78
116
|
handler: async ({ data }) => { ... },
|
|
79
117
|
options: {
|
|
80
118
|
attempts: 3, // Retry count
|
|
@@ -117,7 +155,31 @@ const stats = await ctx.queue.getStats('default');
|
|
|
117
155
|
// { waiting: 10, active: 2, completed: 100, failed: 5 }
|
|
118
156
|
```
|
|
119
157
|
|
|
120
|
-
##
|
|
158
|
+
## Production Deployment
|
|
159
|
+
|
|
160
|
+
### Running Workers
|
|
161
|
+
|
|
162
|
+
In production, run separate worker processes:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// worker.ts
|
|
166
|
+
import { createWorker } from '@veloxts/queue';
|
|
167
|
+
import { sendWelcomeEmail, processOrder } from './jobs';
|
|
168
|
+
|
|
169
|
+
const worker = await createWorker({
|
|
170
|
+
connection: { url: process.env.REDIS_URL },
|
|
171
|
+
jobs: [sendWelcomeEmail, processOrder],
|
|
172
|
+
concurrency: 5,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Graceful shutdown
|
|
176
|
+
process.on('SIGTERM', async () => {
|
|
177
|
+
await worker.close();
|
|
178
|
+
process.exit(0);
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### CLI Commands
|
|
121
183
|
|
|
122
184
|
```bash
|
|
123
185
|
velox queue:work # Start queue worker
|
|
@@ -125,3 +187,36 @@ velox queue:work --queue=high # Process specific queue
|
|
|
125
187
|
velox queue:failed # List failed jobs
|
|
126
188
|
velox queue:retry <id> # Retry a failed job
|
|
127
189
|
```
|
|
190
|
+
|
|
191
|
+
### Production Checklist
|
|
192
|
+
|
|
193
|
+
1. **Redis for job persistence** - Required for BullMQ
|
|
194
|
+
2. **Separate worker processes** - Don't process jobs in web server
|
|
195
|
+
3. **Graceful shutdown** - Allow in-progress jobs to complete
|
|
196
|
+
4. **Failed job monitoring** - Alert on job failures
|
|
197
|
+
5. **Concurrency tuning** - Match to your workload
|
|
198
|
+
|
|
199
|
+
### Recommended Redis providers
|
|
200
|
+
|
|
201
|
+
- [Upstash](https://upstash.com) - Serverless, pay-per-request
|
|
202
|
+
- [Redis Cloud](https://redis.com/cloud) - Managed Redis
|
|
203
|
+
- [Railway](https://railway.app) - Simple Redis add-on
|
|
204
|
+
|
|
205
|
+
## Standalone Usage
|
|
206
|
+
|
|
207
|
+
Use queue outside of Fastify request context (CLI commands, scripts):
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import { getQueue, closeQueue } from '@veloxts/queue';
|
|
211
|
+
|
|
212
|
+
// Get standalone queue instance
|
|
213
|
+
const queue = await getQueue({
|
|
214
|
+
driver: 'bullmq',
|
|
215
|
+
config: { url: process.env.REDIS_URL },
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
await queue.dispatch(myJob, { data: 'value' });
|
|
219
|
+
|
|
220
|
+
// Clean up when done
|
|
221
|
+
await closeQueue();
|
|
222
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veloxts/queue",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.88",
|
|
4
4
|
"description": "Background job processing for VeloxTS framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
"ioredis": "5.6.1",
|
|
28
28
|
"superjson": "2.2.2",
|
|
29
29
|
"zod": "3.24.4",
|
|
30
|
-
"@veloxts/core": "0.6.
|
|
30
|
+
"@veloxts/core": "0.6.88"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@biomejs/biome": "2.0.0",
|
|
34
|
-
"@types/node": "
|
|
34
|
+
"@types/node": "25.0.3",
|
|
35
35
|
"@vitest/coverage-v8": "4.0.16",
|
|
36
36
|
"fastify": "5.6.2",
|
|
37
|
-
"typescript": "5.
|
|
37
|
+
"typescript": "5.9.3",
|
|
38
38
|
"vitest": "4.0.16",
|
|
39
|
-
"@veloxts/testing": "0.6.
|
|
39
|
+
"@veloxts/testing": "0.6.88"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"fastify": "^5.0.0"
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
|
+
"homepage": "https://veloxts.dev/",
|
|
47
48
|
"repository": {
|
|
48
49
|
"type": "git",
|
|
49
50
|
"url": "https://github.com/veloxts/velox-ts-framework.git",
|