smart_message 0.0.8 → 0.0.10

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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.irbrc +24 -0
  4. data/CHANGELOG.md +119 -0
  5. data/Gemfile.lock +6 -1
  6. data/README.md +389 -17
  7. data/docs/README.md +3 -1
  8. data/docs/addressing.md +119 -13
  9. data/docs/architecture.md +184 -46
  10. data/docs/dead_letter_queue.md +673 -0
  11. data/docs/dispatcher.md +87 -0
  12. data/docs/examples.md +59 -1
  13. data/docs/getting-started.md +8 -1
  14. data/docs/logging.md +382 -326
  15. data/docs/message_deduplication.md +488 -0
  16. data/docs/message_filtering.md +451 -0
  17. data/examples/01_point_to_point_orders.rb +54 -53
  18. data/examples/02_publish_subscribe_events.rb +14 -10
  19. data/examples/03_many_to_many_chat.rb +16 -8
  20. data/examples/04_redis_smart_home_iot.rb +20 -10
  21. data/examples/05_proc_handlers.rb +12 -11
  22. data/examples/06_custom_logger_example.rb +95 -100
  23. data/examples/07_error_handling_scenarios.rb +4 -2
  24. data/examples/08_entity_addressing_basic.rb +18 -6
  25. data/examples/08_entity_addressing_with_filtering.rb +27 -9
  26. data/examples/09_dead_letter_queue_demo.rb +559 -0
  27. data/examples/09_regex_filtering_microservices.rb +407 -0
  28. data/examples/10_header_block_configuration.rb +263 -0
  29. data/examples/10_message_deduplication.rb +209 -0
  30. data/examples/11_global_configuration_example.rb +219 -0
  31. data/examples/README.md +102 -0
  32. data/examples/dead_letters.jsonl +12 -0
  33. data/examples/performance_metrics/benchmark_results_ractor_20250818_205603.json +135 -0
  34. data/examples/performance_metrics/benchmark_results_ractor_20250818_205831.json +135 -0
  35. data/examples/performance_metrics/benchmark_results_test_20250818_204942.json +130 -0
  36. data/examples/performance_metrics/benchmark_results_threadpool_20250818_204942.json +130 -0
  37. data/examples/performance_metrics/benchmark_results_threadpool_20250818_204959.json +130 -0
  38. data/examples/performance_metrics/benchmark_results_threadpool_20250818_205044.json +130 -0
  39. data/examples/performance_metrics/benchmark_results_threadpool_20250818_205109.json +130 -0
  40. data/examples/performance_metrics/benchmark_results_threadpool_20250818_205252.json +130 -0
  41. data/examples/performance_metrics/benchmark_results_unknown_20250819_172852.json +130 -0
  42. data/examples/performance_metrics/compare_benchmarks.rb +519 -0
  43. data/examples/performance_metrics/dead_letters.jsonl +3100 -0
  44. data/examples/performance_metrics/performance_benchmark.rb +344 -0
  45. data/examples/show_logger.rb +367 -0
  46. data/examples/show_me.rb +145 -0
  47. data/examples/temp.txt +94 -0
  48. data/examples/tmux_chat/bot_agent.rb +4 -2
  49. data/examples/tmux_chat/human_agent.rb +4 -2
  50. data/examples/tmux_chat/room_monitor.rb +4 -2
  51. data/examples/tmux_chat/shared_chat_system.rb +6 -3
  52. data/lib/smart_message/addressing.rb +259 -0
  53. data/lib/smart_message/base.rb +123 -599
  54. data/lib/smart_message/circuit_breaker.rb +2 -1
  55. data/lib/smart_message/configuration.rb +199 -0
  56. data/lib/smart_message/ddq/base.rb +71 -0
  57. data/lib/smart_message/ddq/memory.rb +109 -0
  58. data/lib/smart_message/ddq/redis.rb +168 -0
  59. data/lib/smart_message/ddq.rb +31 -0
  60. data/lib/smart_message/dead_letter_queue.rb +27 -10
  61. data/lib/smart_message/deduplication.rb +174 -0
  62. data/lib/smart_message/dispatcher.rb +259 -61
  63. data/lib/smart_message/header.rb +5 -0
  64. data/lib/smart_message/logger/base.rb +21 -1
  65. data/lib/smart_message/logger/default.rb +88 -138
  66. data/lib/smart_message/logger/lumberjack.rb +324 -0
  67. data/lib/smart_message/logger/null.rb +81 -0
  68. data/lib/smart_message/logger.rb +17 -9
  69. data/lib/smart_message/messaging.rb +100 -0
  70. data/lib/smart_message/plugins.rb +132 -0
  71. data/lib/smart_message/serializer/base.rb +25 -8
  72. data/lib/smart_message/serializer/json.rb +5 -4
  73. data/lib/smart_message/subscription.rb +196 -0
  74. data/lib/smart_message/transport/base.rb +72 -41
  75. data/lib/smart_message/transport/memory_transport.rb +7 -5
  76. data/lib/smart_message/transport/redis_transport.rb +15 -45
  77. data/lib/smart_message/transport/stdout_transport.rb +18 -8
  78. data/lib/smart_message/transport.rb +1 -34
  79. data/lib/smart_message/utilities.rb +142 -0
  80. data/lib/smart_message/version.rb +1 -1
  81. data/lib/smart_message/versioning.rb +85 -0
  82. data/lib/smart_message/wrapper.rb.bak +132 -0
  83. data/lib/smart_message.rb +74 -28
  84. data/smart_message.gemspec +3 -0
  85. metadata +83 -3
  86. data/lib/smart_message/serializer.rb +0 -10
  87. data/lib/smart_message/wrapper.rb +0 -43
data/docs/README.md CHANGED
@@ -17,11 +17,13 @@ Welcome to the comprehensive documentation for SmartMessage, a Ruby gem that abs
17
17
  - [SmartMessage::Base](base.md)
18
18
  - [Property System](properties.md)
19
19
  - [Entity Addressing](addressing.md)
20
+ - [Message Filtering](message_filtering.md)
20
21
  - [Transport Layer](transports.md)
21
22
  - [Serializers](serializers.md)
22
23
  - [Logging System](logging.md)
23
24
  - [Dispatcher & Routing](dispatcher.md)
24
25
  - [Message Headers](headers.md)
26
+ - [Dead Letter Queue](dead_letter_queue.md)
25
27
 
26
28
  ### Advanced Topics
27
29
  - [Custom Transports](custom-transports.md)
@@ -50,6 +52,6 @@ Welcome to the comprehensive documentation for SmartMessage, a Ruby gem that abs
50
52
 
51
53
  ## Version
52
54
 
53
- This documentation is for SmartMessage v0.0.2.
55
+ This documentation is for SmartMessage v0.0.8.
54
56
 
55
57
  For older versions, please check the git tags and corresponding documentation.
data/docs/addressing.md CHANGED
@@ -63,13 +63,14 @@ end
63
63
 
64
64
  ### Class-Level Configuration
65
65
 
66
- Set default addressing for all instances of a message class:
66
+ Set default addressing for all instances of a message class using three different approaches:
67
67
 
68
+ #### Method 1: Direct Class Methods
68
69
  ```ruby
69
70
  class PaymentMessage < SmartMessage::Base
70
71
  version 1
71
72
 
72
- # Class-level addressing
73
+ # Class-level addressing using direct methods
73
74
  from 'payment-service'
74
75
  to 'bank-gateway'
75
76
  reply_to 'payment-service'
@@ -77,6 +78,42 @@ class PaymentMessage < SmartMessage::Base
77
78
  property :amount, required: true
78
79
  property :account_id, required: true
79
80
  end
81
+ ```
82
+
83
+ #### Method 2: Header Block DSL
84
+ ```ruby
85
+ class PaymentMessage < SmartMessage::Base
86
+ version 1
87
+
88
+ # Class-level addressing using header block
89
+ header do
90
+ from 'payment-service'
91
+ to 'bank-gateway'
92
+ reply_to 'payment-service'
93
+ end
94
+
95
+ property :amount, required: true
96
+ property :account_id, required: true
97
+ end
98
+ ```
99
+
100
+ #### Method 3: Mixed Approach
101
+ ```ruby
102
+ class PaymentMessage < SmartMessage::Base
103
+ version 1
104
+
105
+ # You can mix approaches if needed
106
+ header do
107
+ from 'payment-service'
108
+ to 'bank-gateway'
109
+ end
110
+
111
+ # Additional addressing outside the block
112
+ reply_to 'payment-service'
113
+
114
+ property :amount, required: true
115
+ property :account_id, required: true
116
+ end
80
117
 
81
118
  # All instances inherit class addressing
82
119
  payment = PaymentMessage.new(amount: 100.00, account_id: "ACCT-123")
@@ -87,27 +124,54 @@ puts payment._sm_header.reply_to # => 'payment-service'
87
124
 
88
125
  ### Instance-Level Overrides
89
126
 
90
- Override addressing for specific message instances:
127
+ Override addressing for specific message instances using multiple approaches:
91
128
 
129
+ #### Method Chaining
92
130
  ```ruby
93
131
  class FlexibleMessage < SmartMessage::Base
94
- from 'service-a'
95
- to 'service-b'
132
+ header do
133
+ from 'service-a'
134
+ to 'service-b'
135
+ end
96
136
 
97
137
  property :data
98
138
  end
99
139
 
100
- # Override addressing for this instance
140
+ # Override addressing using method chaining
101
141
  message = FlexibleMessage.new(data: "test")
102
142
  message.from('different-sender')
103
- message.to('different-recipient')
104
- message.reply_to('different-reply-service')
143
+ .to('different-recipient')
144
+ .reply_to('different-reply-service')
105
145
 
106
146
  puts message.from # => 'different-sender'
107
147
  puts message.to # => 'different-recipient'
108
148
  puts message.reply_to # => 'different-reply-service'
149
+ ```
150
+
151
+ #### Setter Methods
152
+ ```ruby
153
+ # Override addressing using setter syntax
154
+ message = FlexibleMessage.new(data: "test")
155
+ message.from = 'different-sender'
156
+ message.to = 'different-recipient'
157
+ message.reply_to = 'different-reply-service'
158
+ ```
109
159
 
110
- # Class defaults remain unchanged
160
+ #### Accessing Addressing Values
161
+ ```ruby
162
+ # Three ways to access addressing values
163
+
164
+ # 1. Direct shortcut methods
165
+ puts message.from # => 'different-sender'
166
+ puts message.to # => 'different-recipient'
167
+ puts message.reply_to # => 'different-reply-service'
168
+
169
+ # 2. Via header object
170
+ puts message._sm_header.from # => 'different-sender'
171
+ puts message._sm_header.to # => 'different-recipient'
172
+ puts message._sm_header.reply_to # => 'different-reply-service'
173
+
174
+ # 3. Class defaults remain unchanged
111
175
  puts FlexibleMessage.from # => 'service-a'
112
176
  puts FlexibleMessage.to # => 'service-b'
113
177
  ```
@@ -257,27 +321,69 @@ message.publish # Raises SmartMessage::Errors::ValidationError
257
321
  # => "The property 'from' From entity ID is required for message routing and replies"
258
322
  ```
259
323
 
324
+ ### Checking Address Configuration
325
+ ```ruby
326
+ class ValidatedMessage < SmartMessage::Base
327
+ header do
328
+ from 'my-service'
329
+ to 'target-service'
330
+ end
331
+
332
+ property :data
333
+ end
334
+
335
+ # Class-level checks
336
+ puts ValidatedMessage.from_configured? # => true
337
+ puts ValidatedMessage.to_configured? # => true
338
+ puts ValidatedMessage.reply_to_configured? # => false
339
+ puts ValidatedMessage.reply_to_missing? # => true
340
+
341
+ # Instance-level checks
342
+ message = ValidatedMessage.new(data: "test")
343
+ puts message.from_configured? # => true
344
+ puts message.to_missing? # => false
345
+
346
+ # Reset addressing
347
+ message.reset_from
348
+ puts message.from_configured? # => false
349
+ puts message.from # => nil
350
+ ```
351
+
260
352
  ## Header Access
261
353
 
262
354
  Access addressing information from message headers:
263
355
 
264
356
  ```ruby
265
357
  class SampleMessage < SmartMessage::Base
266
- from 'sample-service'
267
- to 'target-service'
268
- reply_to 'callback-service'
358
+ # Using header block for configuration
359
+ header do
360
+ from 'sample-service'
361
+ to 'target-service'
362
+ reply_to 'callback-service'
363
+ end
269
364
 
270
365
  property :content
271
366
  end
272
367
 
273
368
  message = SampleMessage.new(content: "Hello")
274
- header = message._sm_header
275
369
 
370
+ # Access via shortcut methods (recommended)
371
+ puts message.from # => 'sample-service'
372
+ puts message.to # => 'target-service'
373
+ puts message.reply_to # => 'callback-service'
374
+
375
+ # Access via header object
376
+ header = message._sm_header
276
377
  puts header.from # => 'sample-service'
277
378
  puts header.to # => 'target-service'
278
379
  puts header.reply_to # => 'callback-service'
279
380
  puts header.uuid # => Generated UUID
280
381
  puts header.message_class # => 'SampleMessage'
382
+
383
+ # Headers automatically sync with instance changes
384
+ message.to = 'new-target'
385
+ puts message.to # => 'new-target'
386
+ puts header.to # => 'new-target' (automatically updated)
281
387
  ```
282
388
 
283
389
  ## Integration with Dispatcher
data/docs/architecture.md CHANGED
@@ -16,37 +16,53 @@ SmartMessage is designed around the principle that **messages should be independ
16
16
 
17
17
  ## Architecture Overview
18
18
 
19
- ```
20
- ┌─────────────────────────────────────────────────────────────┐
21
- SmartMessage::Base │
22
- │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐│
23
- │ │ Message │ Transport │ │ Serializer ││
24
- │ │ Properties │ Plugin │ │ Plugin ││
25
- │ │ │ │ │ │ ││
26
- │ │ • user_id │ │ • publish() │ │ • encode() ││
27
- │ │ action │ │ • subscribe() │ │ • decode() ││
28
- │ │ timestamp │ │ • receive() │ ││
29
- │ └─────────────────┘ └─────────────────┘ └─────────────────┘│
30
- └─────────────────────────────────────────────────────────────┘
31
-
32
-
33
- ┌─────────────────────┐
34
- Dispatcher
35
- │ │
36
- Route messages │
37
- │ • Thread pool │
38
- │ • Subscriptions │
39
- └─────────────────────┘
40
-
41
-
42
- ┌─────────────────────┐
43
- │ Message Handlers │
44
- │ │
45
- Default handler │
46
- Block handlers │
47
- │ • Proc handlers │
48
- │ • Method handlers │
49
- └─────────────────────┘
19
+ ```mermaid
20
+ graph TB
21
+ subgraph "SmartMessage Core"
22
+ Base[SmartMessage::Base]
23
+ Header[Message Header<br/>• UUID<br/>• Timestamps<br/>• Addressing]
24
+ Props[Message Properties<br/>• Business Data<br/>• Validation<br/>• Versioning]
25
+ end
26
+
27
+ subgraph "Plugin System"
28
+ Transport[Transport Plugin<br/>• publish()<br/>• subscribe()<br/>• Memory/Redis/STDOUT]
29
+ Serializer[Serializer Plugin<br/>• encode()<br/>• decode()<br/>• JSON/Custom]
30
+ Logger[Logger Plugin<br/>• Structured logging<br/>• Multiple outputs<br/>• Colorization]
31
+ end
32
+
33
+ subgraph "Message Processing"
34
+ Dispatcher[Dispatcher<br/>• Route messages<br/>• Thread pool<br/>• Subscriptions<br/>• DDQ management]
35
+ DDQ[Deduplication Queue<br/>• Handler-scoped<br/>• Memory/Redis storage<br/>• O(1) performance<br/>• Circular buffer]
36
+ Handlers[Message Handlers<br/>• Default handler<br/>• Block handlers<br/>• Proc handlers<br/>• Method handlers]
37
+ end
38
+
39
+ subgraph "Reliability Layer"
40
+ CircuitBreaker[Circuit Breaker<br/>• Failure thresholds<br/>• Automatic fallback<br/>• Recovery detection]
41
+ DLQ[Dead Letter Queue<br/>• Failed messages<br/>• Replay mechanism<br/>• JSON Lines format]
42
+ end
43
+
44
+ subgraph "Monitoring"
45
+ Stats[Statistics<br/>• Message counts<br/>• Processing metrics<br/>• Thread pool status]
46
+ Filters[Message Filtering<br/>• Entity-aware routing<br/>• Regex patterns<br/>• Broadcast handling]
47
+ end
48
+
49
+ Base --> Header
50
+ Base --> Props
51
+ Base --> Transport
52
+ Base --> Serializer
53
+ Base --> Logger
54
+
55
+ Transport --> Dispatcher
56
+ Dispatcher --> DDQ
57
+ Dispatcher --> Handlers
58
+ Dispatcher --> Stats
59
+ Dispatcher --> Filters
60
+
61
+ Transport --> CircuitBreaker
62
+ CircuitBreaker --> DLQ
63
+
64
+ DDQ -.-> Stats
65
+ Handlers -.-> Stats
50
66
  ```
51
67
 
52
68
  ## Core Components
@@ -126,38 +142,84 @@ end
126
142
 
127
143
  ### 4. Dispatcher
128
144
 
129
- Routes incoming messages to appropriate handlers using concurrent processing.
145
+ Routes incoming messages to appropriate handlers using concurrent processing with integrated deduplication.
130
146
 
131
147
  **Key Responsibilities:**
132
148
  - Message routing based on class
133
- - Thread pool management
149
+ - Thread pool management
134
150
  - Subscription catalog management
135
- - Statistics collection
151
+ - Handler-scoped DDQ management
152
+ - Message filtering and statistics collection
136
153
 
137
- **Location:** `lib/smart_message/dispatcher.rb:11-147`
154
+ **Location:** `lib/smart_message/dispatcher.rb`
138
155
 
139
156
  ```ruby
140
157
  dispatcher = SmartMessage::Dispatcher.new
141
158
  dispatcher.add("MyMessage", "MyMessage.process")
142
159
  dispatcher.route(header, payload)
160
+
161
+ # DDQ integration is automatic when enabled
162
+ MyMessage.enable_deduplication!
163
+ ```
164
+
165
+ ### 5. Deduplication Queue (DDQ)
166
+
167
+ Handler-scoped message deduplication system preventing duplicate processing.
168
+
169
+ **Key Responsibilities:**
170
+ - UUID-based duplicate detection
171
+ - Handler isolation (each handler gets own DDQ)
172
+ - Memory and Redis storage backends
173
+ - O(1) performance with hybrid Array + Set data structure
174
+
175
+ **Architecture:**
176
+ ```mermaid
177
+ graph LR
178
+ subgraph "Handler A DDQ"
179
+ A1[Circular Array]
180
+ A2[Lookup Set]
181
+ A3[Mutex Lock]
182
+ end
183
+
184
+ subgraph "Handler B DDQ"
185
+ B1[Circular Array]
186
+ B2[Lookup Set]
187
+ B3[Mutex Lock]
188
+ end
189
+
190
+ Message[Incoming Message<br/>UUID: abc-123] --> Dispatcher
191
+ Dispatcher --> |Check Handler A| A2
192
+ Dispatcher --> |Check Handler B| B2
193
+
194
+ A2 --> |Not Found| ProcessA[Process with Handler A]
195
+ B2 --> |Found| SkipB[Skip Handler B - Duplicate]
196
+
197
+ ProcessA --> |Add UUID| A1
198
+ ProcessA --> |Add UUID| A2
143
199
  ```
144
200
 
145
- ### 5. Message Headers
201
+ **Location:** `lib/smart_message/deduplication.rb`, `lib/smart_message/ddq/`
202
+
203
+ ### 6. Message Headers
146
204
 
147
- Standard metadata attached to every message.
205
+ Standard metadata attached to every message with entity addressing support.
148
206
 
149
207
  **Key Responsibilities:**
150
208
  - Message identification (UUID)
151
- - Routing information (message class)
209
+ - Routing information (message class, version)
152
210
  - Tracking data (timestamps, process IDs)
211
+ - Entity addressing (from, to, reply_to)
153
212
 
154
- **Location:** `lib/smart_message/header.rb:9-20`
213
+ **Location:** `lib/smart_message/header.rb`
155
214
 
156
215
  ```ruby
157
216
  header = message._sm_header
158
217
  puts header.uuid # "550e8400-e29b-41d4-a716-446655440000"
159
218
  puts header.message_class # "MyMessage"
160
219
  puts header.published_at # 2025-08-17 10:30:00 UTC
220
+ puts header.from # "payment-service"
221
+ puts header.to # "order-service"
222
+ puts header.version # 1
161
223
  ```
162
224
 
163
225
  ## Message Lifecycle
@@ -177,17 +239,27 @@ end
177
239
 
178
240
  ### 2. Subscription Phase
179
241
  ```ruby
242
+ # Basic subscription
180
243
  OrderMessage.subscribe
181
- # Registers "OrderMessage.process" with dispatcher
244
+
245
+ # Subscription with filtering
246
+ OrderMessage.subscribe(from: /^payment-.*/, to: 'order-service')
247
+ OrderMessage.subscribe('PaymentService.process', broadcast: true)
248
+
249
+ # Each subscription gets its own DDQ automatically
250
+ # DDQ Key: "OrderMessage:OrderMessage.process"
251
+ # DDQ Key: "OrderMessage:PaymentService.process"
182
252
  ```
183
253
 
184
254
  ### 3. Publishing Phase
185
255
  ```ruby
186
256
  order = OrderMessage.new(order_id: "123", amount: 99.99)
257
+ order.from("order-service").to("payment-service")
187
258
  order.publish
188
- # 1. Creates header with UUID, timestamp, etc.
189
- # 2. Encodes message via serializer
259
+ # 1. Creates header with UUID, timestamp, addressing
260
+ # 2. Encodes message via serializer
190
261
  # 3. Sends via transport
262
+ # 4. Circuit breaker monitors for failures
191
263
  ```
192
264
 
193
265
  ### 4. Receiving Phase
@@ -195,9 +267,10 @@ order.publish
195
267
  # Transport receives message
196
268
  transport.receive(header, payload)
197
269
  # 1. Routes to dispatcher
198
- # 2. Dispatcher finds subscribers
199
- # 3. Spawns thread for processing
200
- # 4. Calls registered message handlers
270
+ # 2. Dispatcher checks DDQ for duplicates per handler
271
+ # 3. Applies message filters (from/to/broadcast)
272
+ # 4. Spawns thread for processing matching handlers
273
+ # 5. Marks UUID as processed in handler's DDQ
201
274
  ```
202
275
 
203
276
  ### 5. Message Handler Processing
@@ -345,11 +418,69 @@ module SmartMessage::Errors
345
418
  end
346
419
  ```
347
420
 
421
+ ## Reliability & Fault Tolerance
422
+
423
+ ### Circuit Breaker Integration
424
+
425
+ SmartMessage integrates BreakerMachines for production-grade reliability:
426
+
427
+ ```ruby
428
+ # Transport operations protected by circuit breakers
429
+ class MyTransport < SmartMessage::Transport::Base
430
+ circuit :transport_publish do
431
+ threshold failures: 5, within: 30.seconds
432
+ reset_after 15.seconds
433
+ fallback SmartMessage::CircuitBreaker::Fallbacks.dead_letter_queue
434
+ end
435
+ end
436
+ ```
437
+
438
+ **Circuit Breaker States:**
439
+ - **Closed**: Normal operation, requests pass through
440
+ - **Open**: Threshold exceeded, requests fail fast
441
+ - **Half-Open**: Testing if service recovered
442
+
443
+ ### Dead Letter Queue
444
+
445
+ Failed messages are automatically captured in the Dead Letter Queue:
446
+
447
+ ```ruby
448
+ # Automatic capture when circuit breaker trips
449
+ message.publish # If transport fails, goes to DLQ
450
+
451
+ # Manual capture for business logic failures
452
+ dlq = SmartMessage::DeadLetterQueue.default
453
+ dlq.enqueue(header, payload, error: "Validation failed")
454
+ ```
455
+
456
+ **DLQ Architecture:**
457
+
458
+ ```mermaid
459
+ graph TB
460
+ Publish[Message Publishing]
461
+ CB[Circuit Breaker<br/>Monitoring]
462
+ Transport[Transport<br/>Success]
463
+ DLQ[Dead Letter Queue<br/>Failure Storage]
464
+ Replay[Replay Mechanism<br/>Manual/Automated]
465
+
466
+ Publish --> CB
467
+ CB --> |Success| Transport
468
+ CB --> |Failure| DLQ
469
+ DLQ --> Replay
470
+ Replay --> |Retry| Publish
471
+ ```
472
+
473
+ **DLQ Features:**
474
+ - JSON Lines format for efficient append operations
475
+ - FIFO queue operations with thread safety
476
+ - Replay capabilities with transport override
477
+ - Administrative tools for filtering and analysis
478
+
348
479
  ## Statistics & Monitoring
349
480
 
350
481
  ### Built-in Statistics
351
482
 
352
- SmartMessage automatically collects processing statistics:
483
+ SmartMessage automatically collects processing statistics including DDQ metrics:
353
484
 
354
485
  ```ruby
355
486
  # Statistics are collected for:
@@ -359,6 +490,11 @@ SS.add(message_class, process_method, 'routed')
359
490
  # Access statistics
360
491
  puts SS.stat
361
492
  puts SS.get("MyMessage", "publish")
493
+
494
+ # DDQ-specific statistics
495
+ stats = OrderMessage.ddq_stats
496
+ puts "DDQ utilization: #{stats[:utilization]}%"
497
+ puts "Current count: #{stats[:current_count]}"
362
498
  ```
363
499
 
364
500
  ### Monitoring Points
@@ -367,6 +503,8 @@ puts SS.get("MyMessage", "publish")
367
503
  2. **Message Routing**: Count of routed messages per processor
368
504
  3. **Thread Pool**: Queue length, completed tasks, running status
369
505
  4. **Transport Status**: Connection status, message counts
506
+ 5. **DDQ Metrics**: Utilization, duplicate detection rates, memory usage
507
+ 6. **Message Filtering**: Filter match rates, entity-aware routing statistics
370
508
 
371
509
  ## Configuration Architecture
372
510