@owlmeans/queue 0.1.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.
- package/LICENSE +21 -0
- package/README.md +363 -0
- package/build/.gitkeep +0 -0
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +2 -0
- package/build/index.js.map +1 -0
- package/package.json +31 -0
- package/src/index.ts +0 -0
- package/tsconfig.json +14 -0
- package/tsconfig.tsbuildinfo +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 OwlMeans Common — Fullstack typescript framework
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
# @owlmeans/queue
|
|
2
|
+
|
|
3
|
+
A foundational queue management system for OwlMeans Common applications. This package provides base interfaces and abstractions for implementing message queues, task queues, and asynchronous processing systems in distributed fullstack applications with a focus on security and proper queue management.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `@owlmeans/queue` package serves as the foundational layer for queue implementations in the OwlMeans ecosystem. It follows the OwlMeans "quadra" pattern where this common package contains shared abstractions that can be extended by:
|
|
8
|
+
|
|
9
|
+
- **Server implementations**: Backend queue processing and management
|
|
10
|
+
- **Client implementations**: Client-side queue interfaces and monitoring
|
|
11
|
+
- **Web implementations**: Web-based queue management dashboards
|
|
12
|
+
- **Native implementations**: Mobile queue synchronization and offline support
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @owlmeans/queue
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Key Concepts
|
|
21
|
+
|
|
22
|
+
### Queue Abstractions
|
|
23
|
+
Base interfaces and types that provide standardized queue functionality across different implementations and backends (Redis, RabbitMQ, AWS SQS, etc.).
|
|
24
|
+
|
|
25
|
+
### Message-based Architecture
|
|
26
|
+
Support for asynchronous, message-based communication patterns that enable loose coupling between microservices and scalable application architectures.
|
|
27
|
+
|
|
28
|
+
### OwlMeans Integration
|
|
29
|
+
Full integration with the OwlMeans Common library ecosystem including context management, authentication, resource management, and error handling.
|
|
30
|
+
|
|
31
|
+
## API Reference
|
|
32
|
+
|
|
33
|
+
*Note: This package currently provides foundational abstractions. Specific implementations are available in backend-specific packages.*
|
|
34
|
+
|
|
35
|
+
### Planned Core Interfaces
|
|
36
|
+
|
|
37
|
+
#### QueueService Interface
|
|
38
|
+
```typescript
|
|
39
|
+
interface QueueService<T = any> extends InitializedService {
|
|
40
|
+
// Core queue operations
|
|
41
|
+
enqueue: (message: T, options?: QueueOptions) => Promise<string>
|
|
42
|
+
dequeue: (options?: DequeueOptions) => Promise<QueueMessage<T> | null>
|
|
43
|
+
peek: (count?: number) => Promise<QueueMessage<T>[]>
|
|
44
|
+
|
|
45
|
+
// Queue management
|
|
46
|
+
size: () => Promise<number>
|
|
47
|
+
purge: () => Promise<number>
|
|
48
|
+
health: () => Promise<QueueHealth>
|
|
49
|
+
|
|
50
|
+
// Batch operations
|
|
51
|
+
enqueueBatch: (messages: T[], options?: QueueOptions) => Promise<string[]>
|
|
52
|
+
dequeueBatch: (count: number, options?: DequeueOptions) => Promise<QueueMessage<T>[]>
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### QueueMessage Interface
|
|
57
|
+
```typescript
|
|
58
|
+
interface QueueMessage<T = any> {
|
|
59
|
+
id: string // Unique message identifier
|
|
60
|
+
payload: T // Message content
|
|
61
|
+
timestamp: Date // Enqueue timestamp
|
|
62
|
+
attempts: number // Processing attempt count
|
|
63
|
+
priority?: number // Message priority (higher = more important)
|
|
64
|
+
delay?: number // Delay before message becomes available
|
|
65
|
+
ttl?: number // Time to live in milliseconds
|
|
66
|
+
retry?: RetryConfig // Retry configuration
|
|
67
|
+
metadata?: Record<string, any> // Additional message metadata
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### QueueOptions Interface
|
|
72
|
+
```typescript
|
|
73
|
+
interface QueueOptions {
|
|
74
|
+
delay?: number // Delay before message becomes available (ms)
|
|
75
|
+
priority?: number // Message priority (0-100)
|
|
76
|
+
maxRetries?: number // Maximum retry attempts
|
|
77
|
+
ttl?: number // Time to live (ms)
|
|
78
|
+
deadLetterQueue?: string // Dead letter queue name
|
|
79
|
+
retryBackoff?: 'fixed' | 'exponential' | 'linear'
|
|
80
|
+
retryDelay?: number // Base retry delay (ms)
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### DequeueOptions Interface
|
|
85
|
+
```typescript
|
|
86
|
+
interface DequeueOptions {
|
|
87
|
+
timeout?: number // Polling timeout (ms)
|
|
88
|
+
visibility?: number // Message visibility timeout (ms)
|
|
89
|
+
waitTime?: number // Long polling wait time (ms)
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Queue Types
|
|
94
|
+
|
|
95
|
+
#### FIFO Queues
|
|
96
|
+
First-in-first-out message processing with guaranteed ordering.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
interface FifoQueueService<T> extends QueueService<T> {
|
|
100
|
+
enforceOrder: boolean
|
|
101
|
+
deduplication: boolean
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### Priority Queues
|
|
106
|
+
Priority-based message processing where higher priority messages are processed first.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
interface PriorityQueueService<T> extends QueueService<T> {
|
|
110
|
+
setPriority: (messageId: string, priority: number) => Promise<void>
|
|
111
|
+
getByPriority: (minPriority: number) => Promise<QueueMessage<T>[]>
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Delay Queues
|
|
116
|
+
Scheduled message delivery with precise timing control.
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
interface DelayQueueService<T> extends QueueService<T> {
|
|
120
|
+
scheduleAt: (message: T, scheduleTime: Date, options?: QueueOptions) => Promise<string>
|
|
121
|
+
scheduleIn: (message: T, delayMs: number, options?: QueueOptions) => Promise<string>
|
|
122
|
+
cancelScheduled: (messageId: string) => Promise<boolean>
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
#### Dead Letter Queues
|
|
127
|
+
Failed message handling with automatic retry and dead letter routing.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
interface DeadLetterQueueService<T> extends QueueService<T> {
|
|
131
|
+
deadLetterQueue: string
|
|
132
|
+
reprocessDeadLetter: (messageId: string) => Promise<void>
|
|
133
|
+
getDeadLetters: () => Promise<QueueMessage<T>[]>
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Processing Models
|
|
138
|
+
|
|
139
|
+
#### Worker Pool Configuration
|
|
140
|
+
```typescript
|
|
141
|
+
interface WorkerPoolConfig {
|
|
142
|
+
concurrency: number // Number of concurrent workers
|
|
143
|
+
maxJobs?: number // Maximum jobs per worker
|
|
144
|
+
retryDelay?: number // Delay between retries (ms)
|
|
145
|
+
stalledInterval?: number // Stalled job check interval (ms)
|
|
146
|
+
maxStalledCount?: number // Maximum stalled count before job fails
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Batch Processing
|
|
151
|
+
```typescript
|
|
152
|
+
interface BatchProcessor<T, R> {
|
|
153
|
+
process: (messages: QueueMessage<T>[]) => Promise<R[]>
|
|
154
|
+
batchSize: number
|
|
155
|
+
flushInterval?: number // Auto-flush interval (ms)
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Queue Health and Monitoring
|
|
160
|
+
|
|
161
|
+
#### QueueHealth Interface
|
|
162
|
+
```typescript
|
|
163
|
+
interface QueueHealth {
|
|
164
|
+
status: 'healthy' | 'degraded' | 'unhealthy'
|
|
165
|
+
pending: number // Number of pending messages
|
|
166
|
+
processing: number // Number of messages being processed
|
|
167
|
+
failed: number // Number of failed messages
|
|
168
|
+
completed: number // Number of completed messages
|
|
169
|
+
lastActivity: Date // Last queue activity timestamp
|
|
170
|
+
metrics: QueueMetrics
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### QueueMetrics Interface
|
|
175
|
+
```typescript
|
|
176
|
+
interface QueueMetrics {
|
|
177
|
+
throughput: {
|
|
178
|
+
messagesPerSecond: number
|
|
179
|
+
averageProcessingTime: number
|
|
180
|
+
}
|
|
181
|
+
errors: {
|
|
182
|
+
errorRate: number
|
|
183
|
+
lastError?: Error
|
|
184
|
+
errorCount: number
|
|
185
|
+
}
|
|
186
|
+
capacity: {
|
|
187
|
+
utilizationPercent: number
|
|
188
|
+
maxCapacity?: number
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Usage Examples
|
|
194
|
+
|
|
195
|
+
### Basic Queue Service Registration
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { createService } from '@owlmeans/context'
|
|
199
|
+
import { QueueService } from '@owlmeans/queue'
|
|
200
|
+
|
|
201
|
+
// Register a queue service (implementation-specific)
|
|
202
|
+
const queueService = createService<QueueService>('message-queue', {
|
|
203
|
+
// Implementation-specific configuration
|
|
204
|
+
async enqueue(message, options) {
|
|
205
|
+
// Implementation logic
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
async dequeue(options) {
|
|
209
|
+
// Implementation logic
|
|
210
|
+
}
|
|
211
|
+
}, (service) => async () => {
|
|
212
|
+
// Service initialization
|
|
213
|
+
service.initialized = true
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
context.registerService(queueService)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Message Processing with Error Handling
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// Message processing with retry logic
|
|
223
|
+
const processMessages = async () => {
|
|
224
|
+
try {
|
|
225
|
+
const message = await queueService.dequeue({ timeout: 5000 })
|
|
226
|
+
|
|
227
|
+
if (message) {
|
|
228
|
+
try {
|
|
229
|
+
await processMessage(message.payload)
|
|
230
|
+
console.log(`Processed message ${message.id}`)
|
|
231
|
+
} catch (error) {
|
|
232
|
+
if (message.attempts < 3) {
|
|
233
|
+
// Retry with exponential backoff
|
|
234
|
+
await queueService.enqueue(message.payload, {
|
|
235
|
+
delay: Math.pow(2, message.attempts) * 1000,
|
|
236
|
+
maxRetries: 3
|
|
237
|
+
})
|
|
238
|
+
} else {
|
|
239
|
+
// Send to dead letter queue
|
|
240
|
+
console.error(`Message ${message.id} failed after max retries`)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error('Queue processing error:', error)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Queue Health Monitoring
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
// Monitor queue health
|
|
254
|
+
const monitorQueue = async () => {
|
|
255
|
+
const health = await queueService.health()
|
|
256
|
+
|
|
257
|
+
if (health.status === 'unhealthy') {
|
|
258
|
+
console.error('Queue is unhealthy:', health.metrics)
|
|
259
|
+
// Alert administrators or trigger auto-scaling
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
console.log(`Queue status: ${health.status}`)
|
|
263
|
+
console.log(`Pending messages: ${health.pending}`)
|
|
264
|
+
console.log(`Throughput: ${health.metrics.throughput.messagesPerSecond}/s`)
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Implementation Packages
|
|
269
|
+
|
|
270
|
+
This base package is extended by implementation-specific packages:
|
|
271
|
+
|
|
272
|
+
### Backend Implementations
|
|
273
|
+
- **@owlmeans/redis**: Redis-based queue implementation with persistence
|
|
274
|
+
- **@owlmeans/mongo**: MongoDB-based queue with document storage
|
|
275
|
+
- **@owlmeans/queue-memory**: In-memory queue for development and testing
|
|
276
|
+
|
|
277
|
+
### Client-side Implementations
|
|
278
|
+
- **@owlmeans/client-queue**: Client-side queue interfaces and state management
|
|
279
|
+
- **@owlmeans/web-queue**: Web-based queue management dashboard
|
|
280
|
+
- **@owlmeans/native-queue**: Mobile queue synchronization and offline support
|
|
281
|
+
|
|
282
|
+
## Integration with OwlMeans Ecosystem
|
|
283
|
+
|
|
284
|
+
### Context Integration
|
|
285
|
+
```typescript
|
|
286
|
+
import { makeBasicContext } from '@owlmeans/context'
|
|
287
|
+
import { QueueService } from '@owlmeans/queue'
|
|
288
|
+
|
|
289
|
+
const context = makeBasicContext(config)
|
|
290
|
+
const queueService = context.service<QueueService>('queue')
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Authentication and Security
|
|
294
|
+
Queue services integrate with OwlMeans authentication system to ensure secure message processing:
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
// Authenticated queue operations
|
|
298
|
+
const authenticatedEnqueue = async (message: any, token: string) => {
|
|
299
|
+
// Validation and authentication logic
|
|
300
|
+
if (await validateToken(token)) {
|
|
301
|
+
return queueService.enqueue(message)
|
|
302
|
+
}
|
|
303
|
+
throw new Error('Unauthorized queue access')
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Error Handling
|
|
308
|
+
Integration with OwlMeans error handling system:
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
import { ResilientError } from '@owlmeans/error'
|
|
312
|
+
|
|
313
|
+
try {
|
|
314
|
+
await queueService.enqueue(message)
|
|
315
|
+
} catch (error) {
|
|
316
|
+
throw new ResilientError('QUEUE_ENQUEUE_FAILED', 'Failed to enqueue message', {
|
|
317
|
+
originalError: error,
|
|
318
|
+
messageId: message.id
|
|
319
|
+
})
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Best Practices
|
|
324
|
+
|
|
325
|
+
1. **Message Idempotency**: Design message handlers to be idempotent to handle duplicate processing
|
|
326
|
+
2. **Error Handling**: Implement proper retry logic with exponential backoff
|
|
327
|
+
3. **Dead Letter Queues**: Use dead letter queues for failed messages that exceed retry limits
|
|
328
|
+
4. **Monitoring**: Implement queue health monitoring and alerting
|
|
329
|
+
5. **Capacity Planning**: Monitor queue depth and processing rates to plan capacity
|
|
330
|
+
6. **Security**: Always validate and authenticate queue operations in production
|
|
331
|
+
|
|
332
|
+
## Related Packages
|
|
333
|
+
|
|
334
|
+
- **@owlmeans/context**: Context management and service registration
|
|
335
|
+
- **@owlmeans/resource**: Base resource system for queue persistence
|
|
336
|
+
- **@owlmeans/auth**: Authentication and authorization
|
|
337
|
+
- **@owlmeans/error**: Error handling and resilient error management
|
|
338
|
+
- **@owlmeans/redis**: Redis-based queue implementation
|
|
339
|
+
- **@owlmeans/mongo**: MongoDB-based queue implementation
|
|
340
|
+
|
|
341
|
+
## Development Status
|
|
342
|
+
|
|
343
|
+
This package provides foundational abstractions for queue systems. For immediate queue functionality, use implementation-specific packages:
|
|
344
|
+
|
|
345
|
+
1. **Redis Queues**: `@owlmeans/redis` for production queue implementations
|
|
346
|
+
2. **Memory Queues**: `@owlmeans/queue-memory` for development and testing
|
|
347
|
+
3. **Custom Implementation**: Extend these interfaces for custom queue backends
|
|
348
|
+
|
|
349
|
+
## TypeScript Support
|
|
350
|
+
|
|
351
|
+
This package is written in TypeScript and provides full type safety for queue operations:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import type { QueueService, QueueMessage, QueueOptions } from '@owlmeans/queue'
|
|
355
|
+
|
|
356
|
+
interface UserMessage {
|
|
357
|
+
userId: string
|
|
358
|
+
action: 'create' | 'update' | 'delete'
|
|
359
|
+
data: Record<string, any>
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const userQueue: QueueService<UserMessage> = context.service('user-queue')
|
|
363
|
+
```
|
package/build/.gitkeep
ADDED
|
File without changes
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/build/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@owlmeans/queue",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "tsc -b",
|
|
7
|
+
"dev": "sleep 234 && nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
|
|
8
|
+
"watch": "tsc -b -w --preserveWatchOutput --pretty"
|
|
9
|
+
},
|
|
10
|
+
"main": "build/index.js",
|
|
11
|
+
"module": "build/index.js",
|
|
12
|
+
"types": "build/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./build/index.js",
|
|
16
|
+
"require": "./build/index.js",
|
|
17
|
+
"default": "./build/index.js",
|
|
18
|
+
"module": "./build/index.js",
|
|
19
|
+
"types": "./build/index.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^22.7.8",
|
|
24
|
+
"nodemon": "^3.1.7",
|
|
25
|
+
"typescript": "^5.6.3"
|
|
26
|
+
},
|
|
27
|
+
"private": false,
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/index.ts
ADDED
|
File without changes
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": [
|
|
3
|
+
"../tsconfig.default.json",
|
|
4
|
+
],
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"rootDir": "./src/", /* Specify the root folder within your source files. */
|
|
7
|
+
"outDir": "./build/", /* Specify an output folder for all emitted files. */
|
|
8
|
+
},
|
|
9
|
+
"exclude": [
|
|
10
|
+
"./dist/**/*",
|
|
11
|
+
"./build/**/*",
|
|
12
|
+
"./*.ts"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/index.ts"],"version":"5.6.3"}
|