glide-mq 0.4.0 → 0.4.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 +143 -8
- package/demo/README.md +169 -0
- package/demo/dashboard-server.ts +474 -0
- package/demo/index.ts +502 -0
- package/demo/package-lock.json +2051 -0
- package/demo/package.json +26 -0
- package/dist/flow-producer.d.ts.map +1 -1
- package/dist/flow-producer.js +1 -1
- package/dist/flow-producer.js.map +1 -1
- package/dist/functions/index.d.ts +10 -4
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +173 -13
- package/dist/functions/index.js.map +1 -1
- package/dist/graceful-shutdown.d.ts +5 -1
- package/dist/graceful-shutdown.d.ts.map +1 -1
- package/dist/graceful-shutdown.js +31 -11
- package/dist/graceful-shutdown.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/job.d.ts +2 -0
- package/dist/job.d.ts.map +1 -1
- package/dist/job.js +4 -0
- package/dist/job.js.map +1 -1
- package/dist/queue.d.ts.map +1 -1
- package/dist/queue.js +50 -11
- package/dist/queue.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/worker.d.ts +11 -1
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +37 -3
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ No-op processor, Valkey 8.0, single node.
|
|
|
46
46
|
npm install glide-mq
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
Requires Node.js 20+ and a running Valkey (7.
|
|
49
|
+
Requires Node.js 20+ and a running Valkey (7.0+) or Redis (7.0+) instance for FUNCTION support.
|
|
50
50
|
|
|
51
51
|
## Quick Start
|
|
52
52
|
|
|
@@ -100,7 +100,7 @@ worker.on('failed', (job, err) => console.log(`Job ${job.id} failed: ${err.messa
|
|
|
100
100
|
- **QueueEvents** - stream-based event subscription (added, completed, failed, stalled, etc.)
|
|
101
101
|
- **Job schedulers** - cron patterns and fixed intervals for repeatable jobs
|
|
102
102
|
- **Metrics** - getJobCounts, getMetrics
|
|
103
|
-
- **OpenTelemetry** -
|
|
103
|
+
- **OpenTelemetry** - automatic tracing spans for Queue.add and FlowProducer.add operations (optional peer dependency)
|
|
104
104
|
|
|
105
105
|
### Cloud-Native (GLIDE-exclusive)
|
|
106
106
|
- **AZ-Affinity routing** - route reads to same-AZ replicas for lower latency and reduced cross-AZ costs
|
|
@@ -195,17 +195,23 @@ await flow.add({
|
|
|
195
195
|
],
|
|
196
196
|
});
|
|
197
197
|
|
|
198
|
-
// Chain: A -> B -> C (sequential)
|
|
199
|
-
await chain(
|
|
198
|
+
// Chain: A -> B -> C (sequential, each step receives previous result)
|
|
199
|
+
await chain('tasks', [
|
|
200
200
|
{ name: 'step1', data: {} },
|
|
201
201
|
{ name: 'step2', data: {} },
|
|
202
|
-
]);
|
|
202
|
+
], connection);
|
|
203
203
|
|
|
204
|
-
// Group: A + B + C (parallel)
|
|
205
|
-
await group(
|
|
204
|
+
// Group: A + B + C (parallel, parent completes when all children done)
|
|
205
|
+
await group('tasks', [
|
|
206
206
|
{ name: 'task1', data: {} },
|
|
207
207
|
{ name: 'task2', data: {} },
|
|
208
|
-
]);
|
|
208
|
+
], connection);
|
|
209
|
+
|
|
210
|
+
// Chord: run group in parallel, then callback with all results
|
|
211
|
+
await chord('tasks', [
|
|
212
|
+
{ name: 'task1', data: {} },
|
|
213
|
+
{ name: 'task2', data: {} },
|
|
214
|
+
], { name: 'aggregate', data: {} }, connection);
|
|
209
215
|
```
|
|
210
216
|
|
|
211
217
|
### Events
|
|
@@ -219,6 +225,34 @@ events.on('failed', ({ jobId, failedReason }) => {});
|
|
|
219
225
|
events.on('stalled', ({ jobId }) => {});
|
|
220
226
|
```
|
|
221
227
|
|
|
228
|
+
### OpenTelemetry
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
// Install optional peer dependency
|
|
232
|
+
// npm install @opentelemetry/api
|
|
233
|
+
|
|
234
|
+
// Automatic tracing for Queue.add and FlowProducer.add
|
|
235
|
+
const queue = new Queue('tasks', { connection });
|
|
236
|
+
await queue.add('job', data); // Creates span: glide-mq.queue.add
|
|
237
|
+
|
|
238
|
+
// Custom tracer (optional)
|
|
239
|
+
import { setTracer } from 'glide-mq';
|
|
240
|
+
setTracer(customTracerInstance);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Graceful Shutdown
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { gracefulShutdown } from 'glide-mq';
|
|
247
|
+
|
|
248
|
+
const queue = new Queue('tasks', { connection });
|
|
249
|
+
const worker = new Worker('tasks', processor, { connection });
|
|
250
|
+
const events = new QueueEvents('tasks', { connection });
|
|
251
|
+
|
|
252
|
+
// Registers SIGTERM/SIGINT handlers and resolves when all components are closed
|
|
253
|
+
await gracefulShutdown([queue, worker, events]);
|
|
254
|
+
```
|
|
255
|
+
|
|
222
256
|
## Cluster Mode
|
|
223
257
|
|
|
224
258
|
```typescript
|
|
@@ -233,6 +267,107 @@ const connection = {
|
|
|
233
267
|
const queue = new Queue('tasks', { connection });
|
|
234
268
|
```
|
|
235
269
|
|
|
270
|
+
## Testing Mode
|
|
271
|
+
|
|
272
|
+
glide-mq ships a built-in in-memory backend so you can unit-test your job processors **without a running Valkey instance**.
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
import { TestQueue, TestWorker } from 'glide-mq/testing';
|
|
276
|
+
|
|
277
|
+
const queue = new TestQueue('tasks');
|
|
278
|
+
|
|
279
|
+
const worker = new TestWorker(queue, async (job) => {
|
|
280
|
+
return { processed: job.data };
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
worker.on('completed', (job, result) => {
|
|
284
|
+
console.log(`Job ${job.id} done:`, result);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
worker.on('failed', (job, err) => {
|
|
288
|
+
console.error(`Job ${job.id} failed:`, err.message);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
await queue.add('send-email', { to: 'user@example.com' });
|
|
292
|
+
|
|
293
|
+
// Inspect state without touching Valkey
|
|
294
|
+
const counts = await queue.getJobCounts();
|
|
295
|
+
// { waiting: 0, active: 0, delayed: 0, completed: 1, failed: 0 }
|
|
296
|
+
|
|
297
|
+
// Search jobs by name or data fields
|
|
298
|
+
const jobs = await queue.searchJobs({ name: 'send-email', state: 'completed' });
|
|
299
|
+
|
|
300
|
+
await worker.close();
|
|
301
|
+
await queue.close();
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
`TestQueue` and `TestWorker` mirror the real `Queue` / `Worker` public API (add, addBulk, getJob, getJobs, getJobCounts, pause, resume, events, retries, concurrency), making it straightforward to swap implementations between test and production code.
|
|
305
|
+
|
|
306
|
+
## Dashboard
|
|
307
|
+
|
|
308
|
+
glide-mq exposes a REST + Server-Sent Events API that can be consumed by the [`@glidemq/dashboard`](https://github.com/avifenesh/glidemq-dashboard) UI package.
|
|
309
|
+
|
|
310
|
+
### Quick start with the built-in demo server
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
cd demo
|
|
314
|
+
npm install
|
|
315
|
+
npm run dashboard # starts http://localhost:3000
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### REST endpoints
|
|
319
|
+
|
|
320
|
+
| Method | Path | Description |
|
|
321
|
+
|--------|------|-------------|
|
|
322
|
+
| `GET` | `/api/queues` | List all queues with counts and metrics |
|
|
323
|
+
| `GET` | `/api/queues/:name` | Queue details + recent jobs |
|
|
324
|
+
| `GET` | `/api/queues/:name/jobs/:id` | Single job details, state, logs |
|
|
325
|
+
| `POST` | `/api/queues/:name/jobs` | Add a new job |
|
|
326
|
+
| `POST` | `/api/queues/:name/pause` | Pause a queue |
|
|
327
|
+
| `POST` | `/api/queues/:name/resume` | Resume a queue |
|
|
328
|
+
| `POST` | `/api/queues/:name/jobs/:id/retry` | Retry a failed job |
|
|
329
|
+
| `DELETE` | `/api/queues/:name/jobs/:id` | Remove a job |
|
|
330
|
+
| `POST` | `/api/queues/:name/drain` | Drain all waiting jobs |
|
|
331
|
+
| `POST` | `/api/queues/:name/obliterate` | Obliterate queue and all data |
|
|
332
|
+
| `GET` | `/api/events` | SSE stream for real-time job events |
|
|
333
|
+
|
|
334
|
+
### Real-time events via SSE
|
|
335
|
+
|
|
336
|
+
```javascript
|
|
337
|
+
const es = new EventSource('http://localhost:3000/api/events');
|
|
338
|
+
es.onmessage = ({ data }) => {
|
|
339
|
+
const { queue, event, jobId } = JSON.parse(data);
|
|
340
|
+
// event: 'added' | 'completed' | 'failed' | 'progress' | 'stalled' | 'heartbeat'
|
|
341
|
+
console.log(`[${queue}] ${event} – job ${jobId}`);
|
|
342
|
+
};
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Embedding the dashboard server in your own Express app
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
import express from 'express';
|
|
349
|
+
import { Queue, QueueEvents } from 'glide-mq';
|
|
350
|
+
|
|
351
|
+
const app = express();
|
|
352
|
+
app.use(express.json());
|
|
353
|
+
|
|
354
|
+
const queues: Record<string, Queue> = {
|
|
355
|
+
orders: new Queue('orders', { connection }),
|
|
356
|
+
payments: new Queue('payments', { connection }),
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
app.get('/api/queues', async (_req, res) => {
|
|
360
|
+
const data = await Promise.all(
|
|
361
|
+
Object.entries(queues).map(async ([name, q]) => ({
|
|
362
|
+
name,
|
|
363
|
+
counts: await q.getJobCounts(),
|
|
364
|
+
isPaused: await q.isPaused(),
|
|
365
|
+
})),
|
|
366
|
+
);
|
|
367
|
+
res.json(data);
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
236
371
|
## License
|
|
237
372
|
|
|
238
373
|
Apache-2.0
|
package/demo/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# glide-mq Demo Application
|
|
2
|
+
|
|
3
|
+
Comprehensive demonstration of all glide-mq features simulating a complete e-commerce platform.
|
|
4
|
+
|
|
5
|
+
## Features Demonstrated
|
|
6
|
+
|
|
7
|
+
### Core Queue Operations
|
|
8
|
+
- Job processing with progress tracking
|
|
9
|
+
- Bulk operations with Batch API
|
|
10
|
+
- Priority queues with FIFO ordering
|
|
11
|
+
- Delayed/scheduled jobs
|
|
12
|
+
- Job retries with exponential backoff
|
|
13
|
+
- Dead letter queue handling
|
|
14
|
+
|
|
15
|
+
### Advanced Features
|
|
16
|
+
- Deduplication (simple, throttle, debounce)
|
|
17
|
+
- Rate limiting (sliding window)
|
|
18
|
+
- Global concurrency limits
|
|
19
|
+
- Job retention policies
|
|
20
|
+
- Transparent gzip compression
|
|
21
|
+
- Timeout handling
|
|
22
|
+
|
|
23
|
+
### Workflows
|
|
24
|
+
- FlowProducer for parent-child job trees
|
|
25
|
+
- Chain pattern for sequential pipelines
|
|
26
|
+
- Group pattern for parallel execution
|
|
27
|
+
- Complex nested workflows
|
|
28
|
+
|
|
29
|
+
### Observability
|
|
30
|
+
- Real-time event streaming
|
|
31
|
+
- Progress tracking
|
|
32
|
+
- Metrics and job counts
|
|
33
|
+
- Job logs and state tracking
|
|
34
|
+
- Dashboard API integration
|
|
35
|
+
|
|
36
|
+
## Setup
|
|
37
|
+
|
|
38
|
+
1. Install dependencies:
|
|
39
|
+
```bash
|
|
40
|
+
cd demo
|
|
41
|
+
npm install
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
2. Ensure Valkey/Redis is running:
|
|
45
|
+
```bash
|
|
46
|
+
# Single node on port 6379
|
|
47
|
+
valkey-server
|
|
48
|
+
|
|
49
|
+
# Or for cluster mode (optional)
|
|
50
|
+
# Ports 7000-7005
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Running the Demo
|
|
54
|
+
|
|
55
|
+
### Option 1: Full Demo with All Features
|
|
56
|
+
```bash
|
|
57
|
+
npm start
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
This launches:
|
|
61
|
+
- 10 different queue types (orders, payments, inventory, etc.)
|
|
62
|
+
- 10 specialized workers with different configurations
|
|
63
|
+
- 12 demo scenarios showcasing various features
|
|
64
|
+
- Real-time metrics display every 5 seconds
|
|
65
|
+
|
|
66
|
+
### Option 2: Dashboard Server
|
|
67
|
+
```bash
|
|
68
|
+
npm run dashboard
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Opens dashboard API server on http://localhost:3000
|
|
72
|
+
|
|
73
|
+
Features:
|
|
74
|
+
- REST API for queue management
|
|
75
|
+
- Server-Sent Events for real-time updates
|
|
76
|
+
- Queue pause/resume controls
|
|
77
|
+
- Job retry/remove operations
|
|
78
|
+
- Metrics and monitoring
|
|
79
|
+
|
|
80
|
+
## Demo Scenarios
|
|
81
|
+
|
|
82
|
+
1. **Simple Order Processing** - Basic job with progress tracking
|
|
83
|
+
2. **Bulk Inventory Update** - 20 jobs added via addBulk
|
|
84
|
+
3. **Priority Tasks** - Jobs with different priority levels
|
|
85
|
+
4. **Scheduled Notifications** - Delayed job execution
|
|
86
|
+
5. **Payment with Retries** - Automatic retry on failure
|
|
87
|
+
6. **Deduplicated Analytics** - Prevents duplicate events
|
|
88
|
+
7. **E-commerce Workflow** - Complex parent-child job tree
|
|
89
|
+
8. **Sequential Pipeline** - Chain pattern for data processing
|
|
90
|
+
9. **Parallel Broadcast** - Group pattern for notifications
|
|
91
|
+
10. **Large Report Generation** - Compression for big payloads
|
|
92
|
+
11. **Rate-Limited Recommendations** - Throttled processing
|
|
93
|
+
12. **Timeout Handling** - Job timeout demonstration
|
|
94
|
+
|
|
95
|
+
## Queue Types
|
|
96
|
+
|
|
97
|
+
- **orders** - Order processing with progress tracking
|
|
98
|
+
- **payments** - Payment processing with retry logic
|
|
99
|
+
- **inventory** - Rate-limited inventory updates
|
|
100
|
+
- **shipping** - Shipping label generation
|
|
101
|
+
- **notifications** - Multi-channel notifications (email/SMS/push)
|
|
102
|
+
- **analytics** - Event aggregation and metrics
|
|
103
|
+
- **recommendations** - ML recommendation generation
|
|
104
|
+
- **reports** - Long-running report generation
|
|
105
|
+
- **priority-tasks** - Priority-based task execution
|
|
106
|
+
- **dead-letter** - Failed job investigation
|
|
107
|
+
|
|
108
|
+
## API Endpoints (Dashboard Server)
|
|
109
|
+
|
|
110
|
+
- `GET /api/queues` - List all queues with counts
|
|
111
|
+
- `GET /api/queues/:name` - Queue details and jobs
|
|
112
|
+
- `GET /api/queues/:name/jobs/:id` - Specific job details
|
|
113
|
+
- `POST /api/queues/:name/jobs` - Add new job
|
|
114
|
+
- `POST /api/queues/:name/pause` - Pause queue
|
|
115
|
+
- `POST /api/queues/:name/resume` - Resume queue
|
|
116
|
+
- `POST /api/queues/:name/jobs/:id/retry` - Retry failed job
|
|
117
|
+
- `DELETE /api/queues/:name/jobs/:id` - Remove job
|
|
118
|
+
- `POST /api/queues/:name/drain` - Drain queue
|
|
119
|
+
- `POST /api/queues/:name/obliterate` - Obliterate queue
|
|
120
|
+
- `GET /api/events` - SSE stream for real-time updates
|
|
121
|
+
|
|
122
|
+
## Monitoring
|
|
123
|
+
|
|
124
|
+
The demo displays real-time metrics including:
|
|
125
|
+
- Queue counts (waiting, active, delayed, completed, failed)
|
|
126
|
+
- Job progress updates
|
|
127
|
+
- Success/failure events
|
|
128
|
+
- Stalled job detection
|
|
129
|
+
- Worker status
|
|
130
|
+
|
|
131
|
+
## Architecture
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
135
|
+
│ Producer │────▶│ Queue │────▶│ Worker │
|
|
136
|
+
│ (Demo App) │ │ (Valkey) │ │ (Processor) │
|
|
137
|
+
└─────────────┘ └─────────────┘ └─────────────┘
|
|
138
|
+
│
|
|
139
|
+
▼
|
|
140
|
+
┌─────────────┐
|
|
141
|
+
│ Dashboard │
|
|
142
|
+
│ (API/UI) │
|
|
143
|
+
└─────────────┘
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Customization
|
|
147
|
+
|
|
148
|
+
Edit `index.ts` to:
|
|
149
|
+
- Add new queue types
|
|
150
|
+
- Modify worker configurations
|
|
151
|
+
- Create custom scenarios
|
|
152
|
+
- Adjust timing and concurrency
|
|
153
|
+
- Change retry strategies
|
|
154
|
+
|
|
155
|
+
## Troubleshooting
|
|
156
|
+
|
|
157
|
+
- Ensure Valkey/Redis is running on localhost:6379
|
|
158
|
+
- Check Node.js version is 20+
|
|
159
|
+
- Verify all dependencies installed
|
|
160
|
+
- Monitor console for error messages
|
|
161
|
+
- Use dashboard API to inspect job details
|
|
162
|
+
|
|
163
|
+
## Performance Tips
|
|
164
|
+
|
|
165
|
+
- Increase worker concurrency for higher throughput
|
|
166
|
+
- Use bulk operations for batch processing
|
|
167
|
+
- Enable compression for large payloads
|
|
168
|
+
- Configure appropriate retention policies
|
|
169
|
+
- Use priority queues for critical tasks
|