@gravito/stream 1.0.3 → 2.0.0

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.
Files changed (2) hide show
  1. package/README.md +110 -5
  2. package/package.json +5 -2
package/README.md CHANGED
@@ -59,6 +59,48 @@ const consumer = new Consumer(manager, {
59
59
  })
60
60
  ```
61
61
 
62
+ ### 4. Concurrency & Groups
63
+
64
+ ```typescript
65
+ const consumer = new Consumer(manager, {
66
+ queues: ['default'],
67
+ concurrency: 5, // Process up to 5 jobs concurrently
68
+ groupJobsSequential: true // Ensure jobs with same groupId run sequentially (default: true)
69
+ })
70
+ ```
71
+
72
+ Jobs with the same `groupId` will always be processed in order, even with high concurrency. Jobs from different groups (or no group) will run in parallel.
73
+
74
+ ### 5. Polling & Batching Optimization
75
+
76
+ ```typescript
77
+ const consumer = new Consumer(manager, {
78
+ queues: ['default'],
79
+ // Polling Strategy
80
+ pollInterval: 1000, // Initial poll interval
81
+ minPollInterval: 100, // Adaptive: reduce to 100ms when jobs found
82
+ maxPollInterval: 5000, // Adaptive: backoff up to 5s when idle
83
+ backoffMultiplier: 1.5, // Exponential backoff factor
84
+
85
+ // Batch Consumption
86
+ batchSize: 10, // Fetch 10 jobs at once (requires concurrency > 1 for parallel processing)
87
+ concurrency: 10,
88
+
89
+ // Blocking Pop (Redis/SQS)
90
+ useBlocking: true, // Use BLPOP when batchSize=1 (reduces CPU usage)
91
+ blockingTimeout: 5 // Block for 5 seconds
92
+ })
93
+ ```
94
+
95
+ ### 6. Monitoring & Stats
96
+
97
+ ```typescript
98
+ const stats = consumer.getStats()
99
+ console.log(`Processed: ${stats.processed}, Failed: ${stats.failed}`)
100
+
101
+ // Metrics are also included in the heartbeat if monitor is enabled
102
+ ```
103
+
62
104
  ### 2. Enqueue a job
63
105
 
64
106
  ```typescript
@@ -90,6 +132,27 @@ const core = await PlanetCore.boot({
90
132
  })
91
133
  ```
92
134
 
135
+ ### 5. Polling & Batching Optimization
136
+
137
+ ```typescript
138
+ const consumer = new Consumer(manager, {
139
+ queues: ['default'],
140
+ // Polling Strategy
141
+ pollInterval: 1000, // Initial poll interval
142
+ minPollInterval: 100, // Adaptive: reduce to 100ms when jobs found
143
+ maxPollInterval: 5000, // Adaptive: backoff up to 5s when idle
144
+ backoffMultiplier: 1.5, // Exponential backoff factor
145
+
146
+ // Batch Consumption
147
+ batchSize: 10, // Fetch 10 jobs at once (requires concurrency > 1 for parallel processing)
148
+ concurrency: 10,
149
+
150
+ // Blocking Pop (Redis/SQS)
151
+ useBlocking: true, // Use BLPOP when batchSize=1 (reduces CPU usage)
152
+ blockingTimeout: 5 // Block for 5 seconds
153
+ })
154
+ ```
155
+
93
156
  ## Database Driver Example
94
157
 
95
158
  ```typescript
@@ -155,9 +218,8 @@ CREATE TABLE jobs (
155
218
  created_at TIMESTAMP NOT NULL DEFAULT NOW()
156
219
  );
157
220
 
158
- CREATE INDEX idx_jobs_queue_available ON jobs(queue, available_at);
159
- CREATE INDEX idx_jobs_reserved ON jobs(reserved_at);
160
- CREATE INDEX idx_jobs_queue_available ON jobs(queue, available_at);
221
+ -- Optimized index for batch popping with SKIP LOCKED
222
+ CREATE INDEX idx_jobs_queue_available_reserved ON jobs(queue, available_at, reserved_at);
161
223
  CREATE INDEX idx_jobs_reserved ON jobs(reserved_at);
162
224
  ```
163
225
 
@@ -174,7 +236,9 @@ OrbitStream.configure({
174
236
  adapter: new SQLitePersistence(DB), // or MySQLPersistence
175
237
  archiveCompleted: true, // Archive jobs when they complete successfully
176
238
  archiveFailed: true, // Archive jobs when they fail permanently
177
- archiveEnqueued: true // (Audit Mode) Archive jobs immediately when pushed
239
+ archiveEnqueued: true, // (Audit Mode) Archive jobs immediately when pushed
240
+ bufferSize: 100, // (Optional) Batch size for buffered writes. Recommended: 50-200. Default: 0 (disabled)
241
+ flushInterval: 1000 // (Optional) Max time (ms) to wait before flushing buffer. Default: 0
178
242
  }
179
243
  })
180
244
  ```
@@ -189,12 +253,46 @@ When Audit Mode is enabled, every job pushed to the queue is immediately written
189
253
  ## Standalone Worker
190
254
 
191
255
  ```bash
192
- bun run packages/orbit-queue/cli/queue-worker.ts \
256
+ bun run packages/stream/cli/queue-worker.ts \
193
257
  --connection=database \
194
258
  --queues=default,emails \
195
259
  --workers=4
196
260
  ```
197
261
 
262
+ ## Debugging & Monitoring
263
+
264
+ ### Enable Debug Mode
265
+
266
+ Enable verbose logging to see detailed information about job lifecycle events (enqueue, process, complete, fail).
267
+
268
+ ```typescript
269
+ OrbitStream.configure({
270
+ debug: true, // Enable debug logging
271
+ // ...
272
+ })
273
+ ```
274
+
275
+ ```typescript
276
+ const consumer = new Consumer(manager, {
277
+ debug: true, // Enable consumer debug logging
278
+ // ...
279
+ })
280
+ ```
281
+
282
+ ### Monitoring
283
+
284
+ The Consumer emits events that you can listen to for custom monitoring:
285
+
286
+ ```typescript
287
+ consumer.on('job:started', ({ job, queue }) => {
288
+ console.log(`Job ${job.id} started on ${queue}`)
289
+ })
290
+
291
+ consumer.on('job:failed', ({ job, error }) => {
292
+ console.error(`Job ${job.id} failed: ${error.message}`)
293
+ })
294
+ ```
295
+
198
296
  ## API Reference
199
297
 
200
298
  ### Job
@@ -241,6 +339,13 @@ class QueueManager {
241
339
  - **SQSDriver** - standard/FIFO queues and long polling
242
340
  - **RabbitMQDriver** - exchanges, queues, and advanced confirm mode
243
341
 
342
+ ## Best Practices
343
+
344
+ 1. **Idempotency**: Ensure your jobs are idempotent. Jobs may be retried if they fail or if the worker crashes.
345
+ 2. **Granularity**: Keep jobs small and focused. Large jobs can block workers and increase memory usage.
346
+ 3. **Timeouts**: Set appropriate timeouts for your jobs to prevent them from hanging indefinitely.
347
+ 4. **Error Handling**: Use the `failed` method or throw errors to trigger retries. Avoid swallowing errors unless you want to suppress retries.
348
+
244
349
  ## License
245
350
 
246
351
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravito/stream",
3
- "version": "1.0.3",
3
+ "version": "2.0.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -47,7 +47,10 @@
47
47
  "cron-parser": "^5.4.0"
48
48
  },
49
49
  "devDependencies": {
50
+ "@types/ioredis": "^5.0.0",
50
51
  "bun-types": "latest",
52
+ "ioredis": "^5.9.2",
53
+ "mitata": "^1.0.34",
51
54
  "tsup": "^8.5.1",
52
55
  "typescript": "^5.9.3"
53
56
  },
@@ -57,4 +60,4 @@
57
60
  "url": "git+https://github.com/gravito-framework/gravito.git",
58
61
  "directory": "packages/stream"
59
62
  }
60
- }
63
+ }