smart_message 0.0.9 → 0.0.12
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.
- checksums.yaml +4 -4
- data/.github/workflows/deploy-github-pages.yml +38 -0
- data/.gitignore +5 -0
- data/CHANGELOG.md +53 -0
- data/Gemfile.lock +35 -4
- data/README.md +265 -69
- data/Rakefile +29 -4
- data/docs/assets/images/ddq_architecture.svg +130 -0
- data/docs/assets/images/dlq_architecture.svg +115 -0
- data/docs/assets/images/enhanced-dual-publishing.svg +136 -0
- data/docs/assets/images/enhanced-fluent-api.svg +149 -0
- data/docs/assets/images/enhanced-microservices-routing.svg +115 -0
- data/docs/assets/images/enhanced-pattern-matching.svg +107 -0
- data/docs/assets/images/fluent-api-demo.svg +59 -0
- data/docs/assets/images/performance-comparison.svg +161 -0
- data/docs/assets/images/redis-basic-architecture.svg +53 -0
- data/docs/assets/images/redis-enhanced-architecture.svg +88 -0
- data/docs/assets/images/redis-queue-architecture.svg +101 -0
- data/docs/assets/images/smart_message.jpg +0 -0
- data/docs/assets/images/smart_message_walking.jpg +0 -0
- data/docs/assets/images/smartmessage_architecture_overview.svg +173 -0
- data/docs/assets/images/transport-comparison-matrix.svg +171 -0
- data/docs/assets/javascripts/mathjax.js +17 -0
- data/docs/assets/stylesheets/extra.css +51 -0
- data/docs/{addressing.md → core-concepts/addressing.md} +5 -7
- data/docs/{architecture.md → core-concepts/architecture.md} +129 -119
- data/docs/{dispatcher.md → core-concepts/dispatcher.md} +21 -21
- data/docs/{message_filtering.md → core-concepts/message-filtering.md} +2 -3
- data/docs/{message_processing.md → core-concepts/message-processing.md} +17 -17
- data/docs/{troubleshooting.md → development/troubleshooting.md} +7 -7
- data/docs/{examples.md → getting-started/examples.md} +115 -89
- data/docs/{getting-started.md → getting-started/quick-start.md} +47 -18
- data/docs/guides/redis-queue-getting-started.md +697 -0
- data/docs/guides/redis-queue-patterns.md +889 -0
- data/docs/guides/redis-queue-production.md +1091 -0
- data/docs/index.md +64 -0
- data/docs/{dead_letter_queue.md → reference/dead-letter-queue.md} +2 -3
- data/docs/{logging.md → reference/logging.md} +1 -1
- data/docs/reference/message-deduplication.md +489 -0
- data/docs/{proc_handlers_summary.md → reference/proc-handlers.md} +7 -6
- data/docs/{serializers.md → reference/serializers.md} +3 -5
- data/docs/{transports.md → reference/transports.md} +133 -11
- data/docs/transports/memory-transport.md +374 -0
- data/docs/transports/redis-enhanced-transport.md +524 -0
- data/docs/transports/redis-queue-transport.md +1304 -0
- data/docs/transports/redis-transport-comparison.md +496 -0
- data/docs/transports/redis-transport.md +509 -0
- data/examples/README.md +98 -5
- data/examples/city_scenario/911_emergency_call_flow.svg +99 -0
- data/examples/city_scenario/README.md +515 -0
- data/examples/city_scenario/ai_visitor_intelligence_flow.svg +108 -0
- data/examples/city_scenario/citizen.rb +195 -0
- data/examples/city_scenario/city_diagram.svg +125 -0
- data/examples/city_scenario/common/health_monitor.rb +80 -0
- data/examples/city_scenario/common/logger.rb +30 -0
- data/examples/city_scenario/emergency_dispatch_center.rb +270 -0
- data/examples/city_scenario/fire_department.rb +446 -0
- data/examples/city_scenario/fire_emergency_flow.svg +95 -0
- data/examples/city_scenario/health_department.rb +100 -0
- data/examples/city_scenario/health_monitoring_system.svg +130 -0
- data/examples/city_scenario/house.rb +244 -0
- data/examples/city_scenario/local_bank.rb +217 -0
- data/examples/city_scenario/messages/emergency_911_message.rb +81 -0
- data/examples/city_scenario/messages/emergency_resolved_message.rb +43 -0
- data/examples/city_scenario/messages/fire_dispatch_message.rb +43 -0
- data/examples/city_scenario/messages/fire_emergency_message.rb +45 -0
- data/examples/city_scenario/messages/health_check_message.rb +22 -0
- data/examples/city_scenario/messages/health_status_message.rb +35 -0
- data/examples/city_scenario/messages/police_dispatch_message.rb +46 -0
- data/examples/city_scenario/messages/silent_alarm_message.rb +38 -0
- data/examples/city_scenario/police_department.rb +316 -0
- data/examples/city_scenario/redis_monitor.rb +129 -0
- data/examples/city_scenario/redis_stats.rb +743 -0
- data/examples/city_scenario/room_for_improvement.md +240 -0
- data/examples/city_scenario/security_emergency_flow.svg +95 -0
- data/examples/city_scenario/service_internal_architecture.svg +154 -0
- data/examples/city_scenario/smart_message_ai_agent.rb +364 -0
- data/examples/city_scenario/start_demo.sh +236 -0
- data/examples/city_scenario/stop_demo.sh +106 -0
- data/examples/city_scenario/visitor.rb +631 -0
- data/examples/memory/01_message_deduplication_demo.rb +209 -0
- data/examples/{09_dead_letter_queue_demo.rb → memory/02_dead_letter_queue_demo.rb} +13 -40
- data/examples/{01_point_to_point_orders.rb → memory/03_point_to_point_orders.rb} +1 -1
- data/examples/{02_publish_subscribe_events.rb → memory/04_publish_subscribe_events.rb} +2 -2
- data/examples/{03_many_to_many_chat.rb → memory/05_many_to_many_chat.rb} +4 -4
- data/examples/{show_me.rb → memory/06_pretty_print_demo.rb} +1 -1
- data/examples/{05_proc_handlers.rb → memory/07_proc_handlers_demo.rb} +2 -2
- data/examples/{06_custom_logger_example.rb → memory/08_custom_logger_demo.rb} +17 -14
- data/examples/{07_error_handling_scenarios.rb → memory/09_error_handling_demo.rb} +4 -4
- data/examples/{08_entity_addressing_basic.rb → memory/10_entity_addressing_basic.rb} +8 -8
- data/examples/{08_entity_addressing_with_filtering.rb → memory/11_entity_addressing_with_filtering.rb} +6 -6
- data/examples/{09_regex_filtering_microservices.rb → memory/12_regex_filtering_microservices.rb} +2 -2
- data/examples/{10_header_block_configuration.rb → memory/13_header_block_configuration.rb} +6 -6
- data/examples/{11_global_configuration_example.rb → memory/14_global_configuration_demo.rb} +19 -8
- data/examples/{show_logger.rb → memory/15_logger_demo.rb} +1 -1
- data/examples/memory/README.md +163 -0
- data/examples/memory/memory_transport_architecture.svg +90 -0
- data/examples/memory/point_to_point_pattern.svg +94 -0
- data/examples/memory/publish_subscribe_pattern.svg +125 -0
- data/examples/{04_redis_smart_home_iot.rb → redis/01_smart_home_iot_demo.rb} +5 -5
- data/examples/redis/README.md +230 -0
- data/examples/redis/alert_system_flow.svg +127 -0
- data/examples/redis/dashboard_status_flow.svg +107 -0
- data/examples/redis/device_command_flow.svg +113 -0
- data/examples/redis/redis_transport_architecture.svg +115 -0
- data/examples/{smart_home_iot_dataflow.md → redis/smart_home_iot_dataflow.md} +4 -116
- data/examples/redis/smart_home_system_architecture.svg +133 -0
- data/examples/redis_enhanced/README.md +319 -0
- data/examples/redis_enhanced/enhanced_01_basic_patterns.rb +233 -0
- data/examples/redis_enhanced/enhanced_02_fluent_api.rb +331 -0
- data/examples/redis_enhanced/enhanced_03_dual_publishing.rb +281 -0
- data/examples/redis_enhanced/enhanced_04_advanced_routing.rb +419 -0
- data/examples/redis_queue/01_basic_messaging.rb +221 -0
- data/examples/redis_queue/01_comprehensive_examples.rb +508 -0
- data/examples/redis_queue/02_pattern_routing.rb +405 -0
- data/examples/redis_queue/03_fluent_api.rb +422 -0
- data/examples/redis_queue/04_load_balancing.rb +486 -0
- data/examples/redis_queue/05_microservices.rb +735 -0
- data/examples/redis_queue/06_emergency_alerts.rb +777 -0
- data/examples/redis_queue/07_queue_management.rb +587 -0
- data/examples/redis_queue/README.md +366 -0
- data/examples/redis_queue/enhanced_01_basic_patterns.rb +233 -0
- data/examples/redis_queue/enhanced_02_fluent_api.rb +331 -0
- data/examples/redis_queue/enhanced_03_dual_publishing.rb +281 -0
- data/examples/redis_queue/enhanced_04_advanced_routing.rb +419 -0
- data/examples/redis_queue/redis_queue_architecture.svg +148 -0
- data/ideas/README.md +41 -0
- data/ideas/agents.md +1001 -0
- data/ideas/database_transport.md +980 -0
- data/ideas/improvement.md +359 -0
- data/ideas/meshage.md +1788 -0
- data/ideas/message_discovery.md +178 -0
- data/ideas/message_schema.md +1381 -0
- data/lib/smart_message/.idea/.gitignore +8 -0
- data/lib/smart_message/.idea/markdown.xml +6 -0
- data/lib/smart_message/.idea/misc.xml +4 -0
- data/lib/smart_message/.idea/modules.xml +8 -0
- data/lib/smart_message/.idea/smart_message.iml +16 -0
- data/lib/smart_message/.idea/vcs.xml +6 -0
- data/lib/smart_message/addressing.rb +15 -0
- data/lib/smart_message/base.rb +2 -2
- data/lib/smart_message/configuration.rb +1 -1
- data/lib/smart_message/ddq/base.rb +71 -0
- data/lib/smart_message/ddq/memory.rb +109 -0
- data/lib/smart_message/ddq/redis.rb +168 -0
- data/lib/smart_message/ddq.rb +31 -0
- data/lib/smart_message/deduplication.rb +174 -0
- data/lib/smart_message/dispatcher.rb +175 -18
- data/lib/smart_message/logger.rb +15 -4
- data/lib/smart_message/plugins.rb +5 -2
- data/lib/smart_message/serializer.rb +14 -0
- data/lib/smart_message/subscription.rb +10 -7
- data/lib/smart_message/transport/redis_enhanced_transport.rb +399 -0
- data/lib/smart_message/transport/redis_queue_transport.rb +555 -0
- data/lib/smart_message/transport/registry.rb +1 -0
- data/lib/smart_message/transport.rb +34 -1
- data/lib/smart_message/version.rb +1 -1
- data/lib/smart_message.rb +5 -52
- data/mkdocs.yml +184 -0
- data/p2p_plan.md +326 -0
- data/p2p_roadmap.md +287 -0
- data/smart_message.gemspec +2 -0
- data/smart_message.svg +51 -0
- metadata +175 -42
- data/docs/README.md +0 -57
- data/examples/dead_letters.jsonl +0 -12
- data/examples/temp.txt +0 -94
- data/examples/tmux_chat/README.md +0 -283
- data/examples/tmux_chat/bot_agent.rb +0 -278
- data/examples/tmux_chat/human_agent.rb +0 -199
- data/examples/tmux_chat/room_monitor.rb +0 -160
- data/examples/tmux_chat/shared_chat_system.rb +0 -328
- data/examples/tmux_chat/start_chat_demo.sh +0 -190
- data/examples/tmux_chat/stop_chat_demo.sh +0 -22
- /data/docs/{properties.md → core-concepts/properties.md} +0 -0
- /data/docs/{ideas_to_think_about.md → development/ideas.md} +0 -0
@@ -137,6 +137,13 @@ Production-ready Redis pub/sub transport for distributed messaging.
|
|
137
137
|
- Configurable connection parameters
|
138
138
|
- Background message subscription threads
|
139
139
|
|
140
|
+
> **💡 Redis Transport Options:** SmartMessage provides three Redis-based transports:
|
141
|
+
> - **Redis (Basic)** - Simple pub/sub for basic scenarios
|
142
|
+
> - **Redis Enhanced** - Pattern-based routing with backwards compatibility
|
143
|
+
> - **Redis Queue** - Persistent queues with load balancing
|
144
|
+
>
|
145
|
+
> See the [Redis Transport Comparison](../transports/redis-transport-comparison.md) for detailed differences and usage guidance.
|
146
|
+
|
140
147
|
**Usage:**
|
141
148
|
|
142
149
|
```ruby
|
@@ -166,12 +173,12 @@ class OrderMessage < SmartMessage::Base
|
|
166
173
|
url: 'redis://localhost:6379',
|
167
174
|
db: 1
|
168
175
|
)
|
169
|
-
serializer SmartMessage::Serializer::
|
176
|
+
serializer SmartMessage::Serializer::Json.new
|
170
177
|
end
|
171
178
|
|
172
|
-
def self.process(
|
173
|
-
|
174
|
-
order =
|
179
|
+
def self.process(decoded_message)
|
180
|
+
# decoded_message is already a message instance
|
181
|
+
order = decoded_message
|
175
182
|
puts "Processing order #{order.order_id} for $#{order.amount}"
|
176
183
|
# Your business logic here
|
177
184
|
end
|
@@ -243,7 +250,7 @@ redis_transport = SmartMessage::Transport.create(:redis,
|
|
243
250
|
[OrderMessage, PaymentMessage, ShippingMessage].each do |msg_class|
|
244
251
|
msg_class.config do
|
245
252
|
transport redis_transport
|
246
|
-
serializer SmartMessage::Serializer::
|
253
|
+
serializer SmartMessage::Serializer::Json.new
|
247
254
|
end
|
248
255
|
|
249
256
|
# Subscribe to each message type (creates separate Redis subscriptions)
|
@@ -285,7 +292,7 @@ class ProductionMessage < SmartMessage::Base
|
|
285
292
|
reconnect_attempts: 10,
|
286
293
|
reconnect_delay: 5
|
287
294
|
)
|
288
|
-
serializer SmartMessage::Serializer::
|
295
|
+
serializer SmartMessage::Serializer::Json.new
|
289
296
|
logger Logger.new(STDOUT)
|
290
297
|
end
|
291
298
|
end
|
@@ -302,7 +309,7 @@ class TestMessage < SmartMessage::Base
|
|
302
309
|
db: 15, # Use separate database for tests
|
303
310
|
auto_subscribe: true
|
304
311
|
)
|
305
|
-
serializer SmartMessage::Serializer::
|
312
|
+
serializer SmartMessage::Serializer::Json.new
|
306
313
|
end
|
307
314
|
end
|
308
315
|
|
@@ -313,6 +320,121 @@ def setup
|
|
313
320
|
end
|
314
321
|
```
|
315
322
|
|
323
|
+
### Redis Enhanced Transport
|
324
|
+
|
325
|
+
Advanced Redis transport with intelligent pattern-based routing and RabbitMQ-style capabilities.
|
326
|
+
|
327
|
+
**Features:**
|
328
|
+
- Pattern-based subscriptions with wildcard support (`*` matching)
|
329
|
+
- Dual channel publishing for backwards compatibility
|
330
|
+
- Fluent API for building complex subscription patterns
|
331
|
+
- Enhanced routing with 3-part channel names: `message_type.from.to`
|
332
|
+
- Convenience methods for common routing patterns
|
333
|
+
- Service-oriented messaging patterns
|
334
|
+
|
335
|
+

|
336
|
+
|
337
|
+
**Usage:**
|
338
|
+
|
339
|
+
```ruby
|
340
|
+
# Create enhanced transport
|
341
|
+
transport = SmartMessage::Transport::RedisEnhancedTransport.new(
|
342
|
+
url: 'redis://localhost:6379',
|
343
|
+
db: 0,
|
344
|
+
auto_subscribe: true
|
345
|
+
)
|
346
|
+
|
347
|
+
# Configure message with enhanced transport
|
348
|
+
class OrderMessage < SmartMessage::Base
|
349
|
+
from 'e-commerce-api'
|
350
|
+
to 'order-processor'
|
351
|
+
|
352
|
+
transport transport
|
353
|
+
serializer SmartMessage::Serializer::Json.new
|
354
|
+
|
355
|
+
property :order_id, required: true
|
356
|
+
property :amount, required: true
|
357
|
+
end
|
358
|
+
|
359
|
+
# Pattern-based subscriptions
|
360
|
+
transport.subscribe_pattern("ordermessage.*.*") # All order messages
|
361
|
+
transport.subscribe_pattern("*.payment_gateway.*") # All from payment gateway
|
362
|
+
transport.subscribe_to_recipient('order-processor') # Convenience method
|
363
|
+
transport.subscribe_to_alerts # Emergency patterns
|
364
|
+
|
365
|
+
# Fluent API subscriptions
|
366
|
+
transport.where.from('web-app').to('user-service').subscribe
|
367
|
+
transport.where.type('OrderMessage').from('api').subscribe
|
368
|
+
transport.where.from('monitoring').subscribe
|
369
|
+
|
370
|
+
# Publishing (goes to BOTH channels for compatibility)
|
371
|
+
order = OrderMessage.new(order_id: 'ORD-123', amount: 99.99)
|
372
|
+
order.publish
|
373
|
+
# Publishes to:
|
374
|
+
# - "OrderMessage" (original format)
|
375
|
+
# - "ordermessage.e_commerce_api.order_processor" (enhanced format)
|
376
|
+
```
|
377
|
+
|
378
|
+
**Pattern Wildcards:**
|
379
|
+
- `*` - Matches exactly one segment
|
380
|
+
- `ordermessage.*.*` - All order messages regardless of from/to
|
381
|
+
- `*.payment_service.*` - All messages from payment service
|
382
|
+
- `*.*.order_processor` - All messages to order processor
|
383
|
+
|
384
|
+
**Convenience Methods:**
|
385
|
+
```ruby
|
386
|
+
transport.subscribe_to_recipient('service-name') # *.*.service-name
|
387
|
+
transport.subscribe_from_sender('api-gateway') # *.api-gateway.*
|
388
|
+
transport.subscribe_to_type('OrderMessage') # ordermessage.*.*
|
389
|
+
transport.subscribe_to_alerts # Multiple alert patterns
|
390
|
+
transport.subscribe_to_broadcasts # *.*.broadcast
|
391
|
+
```
|
392
|
+
|
393
|
+
**Fluent API:**
|
394
|
+
```ruby
|
395
|
+
# Single conditions
|
396
|
+
transport.where.from('api').subscribe # *.api.*
|
397
|
+
transport.where.to('database').subscribe # *.*.database
|
398
|
+
transport.where.type('LogMessage').subscribe # logmessage.*.*
|
399
|
+
|
400
|
+
# Combined conditions
|
401
|
+
transport.where.from('web').to('api').subscribe # *.web.api
|
402
|
+
transport.where.type('Order').from('shop').subscribe # order.shop.*
|
403
|
+
```
|
404
|
+
|
405
|
+
**Options:**
|
406
|
+
- `url` (String): Redis connection URL (default: 'redis://localhost:6379')
|
407
|
+
- `db` (Integer): Redis database number (default: 0)
|
408
|
+
- `auto_subscribe` (Boolean): Automatically start subscriber threads (default: true)
|
409
|
+
- `reconnect_attempts` (Integer): Connection retry attempts (default: 5)
|
410
|
+
- `reconnect_delay` (Integer): Delay between retries in seconds (default: 1)
|
411
|
+
|
412
|
+
**Backwards Compatibility:**
|
413
|
+
|
414
|
+
The Enhanced Transport maintains full backwards compatibility with the basic Redis transport by publishing to both channel formats:
|
415
|
+
|
416
|
+
```ruby
|
417
|
+
# Enhanced transport publishes to BOTH:
|
418
|
+
# 1. "OrderMessage" (basic format - for backwards compatibility)
|
419
|
+
# 2. "ordermessage.from_service.to_service" (enhanced format - for pattern matching)
|
420
|
+
|
421
|
+
# Basic Redis transport can still subscribe to "OrderMessage"
|
422
|
+
# Enhanced transport can use patterns on the enhanced format
|
423
|
+
```
|
424
|
+
|
425
|
+
**Use Cases:**
|
426
|
+
- Microservices architectures requiring sophisticated routing
|
427
|
+
- Migration from basic Redis transport (maintains compatibility)
|
428
|
+
- Development environments needing flexible message routing
|
429
|
+
- Applications requiring RabbitMQ-style patterns without RabbitMQ setup
|
430
|
+
- Service-to-service communication with intelligent filtering
|
431
|
+
|
432
|
+
**Performance:**
|
433
|
+
- Minimal overhead over basic Redis transport
|
434
|
+
- Client-side pattern matching (slightly higher CPU usage)
|
435
|
+
- Dual publishing increases Redis network traffic by ~2x
|
436
|
+
- Excellent performance for most production scenarios
|
437
|
+
|
316
438
|
## Transport Interface
|
317
439
|
|
318
440
|
All transports must implement the `SmartMessage::Transport::Base` interface:
|
@@ -411,7 +533,7 @@ class OrderMessage < SmartMessage::Base
|
|
411
533
|
# All instances use this transport by default
|
412
534
|
config do
|
413
535
|
transport SmartMessage::Transport.create(:memory, auto_process: true)
|
414
|
-
serializer SmartMessage::Serializer::
|
536
|
+
serializer SmartMessage::Serializer::Json.new
|
415
537
|
end
|
416
538
|
end
|
417
539
|
```
|
@@ -689,7 +811,7 @@ end
|
|
689
811
|
|
690
812
|
## Next Steps
|
691
813
|
|
692
|
-
- [
|
814
|
+
- [Redis Transport Comparison](../transports/redis-transport-comparison.md) - Detailed comparison of Redis, Enhanced, and Queue transports
|
693
815
|
- [Serializers](serializers.md) - Understanding message serialization
|
694
|
-
- [Dispatcher](dispatcher.md) - Message routing and processing
|
695
|
-
- [Examples](examples.md) - Real-world transport usage patterns
|
816
|
+
- [Dispatcher](../core-concepts/dispatcher.md) - Message routing and processing
|
817
|
+
- [Examples](../getting-started/examples.md) - Real-world transport usage patterns
|
@@ -0,0 +1,374 @@
|
|
1
|
+
# Memory Transport
|
2
|
+
|
3
|
+
The **Memory Transport** is an in-memory transport implementation designed for testing, development, and rapid prototyping. It stores messages in memory and provides synchronous processing capabilities.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
The Memory Transport is perfect for:
|
8
|
+
- **Unit testing** - No external dependencies required
|
9
|
+
- **Local development** - Fast, lightweight message processing
|
10
|
+
- **Rapid prototyping** - Quick setup without infrastructure
|
11
|
+
- **Debug and inspection** - Full visibility into message flow
|
12
|
+
|
13
|
+
## Key Features
|
14
|
+
|
15
|
+
- 🧠 **In-Memory Storage** - Messages stored in process memory
|
16
|
+
- ⚡ **Synchronous Processing** - Immediate message processing
|
17
|
+
- 🔍 **Message Inspection** - View and count stored messages
|
18
|
+
- 🔄 **Auto-Processing** - Optional automatic message processing
|
19
|
+
- 🛡️ **Memory Protection** - Configurable message limits to prevent overflow
|
20
|
+
- 🧵 **Thread-Safe** - Mutex-protected operations
|
21
|
+
|
22
|
+
## Configuration
|
23
|
+
|
24
|
+
### Basic Setup
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
# Minimal configuration
|
28
|
+
transport = SmartMessage::Transport::MemoryTransport.new
|
29
|
+
|
30
|
+
# With options
|
31
|
+
transport = SmartMessage::Transport::MemoryTransport.new(
|
32
|
+
auto_process: true, # Process messages immediately (default: true)
|
33
|
+
max_messages: 1000 # Maximum messages to store (default: 1000)
|
34
|
+
)
|
35
|
+
```
|
36
|
+
|
37
|
+
### Using with SmartMessage
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# Configure as default transport
|
41
|
+
SmartMessage.configure do |config|
|
42
|
+
config.default_transport = SmartMessage::Transport::MemoryTransport.new
|
43
|
+
end
|
44
|
+
|
45
|
+
# Use in message class
|
46
|
+
class TestMessage < SmartMessage::Base
|
47
|
+
property :content, required: true
|
48
|
+
|
49
|
+
transport :memory
|
50
|
+
|
51
|
+
def process
|
52
|
+
puts "Processing: #{content}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
## Configuration Options
|
58
|
+
|
59
|
+
| Option | Type | Default | Description |
|
60
|
+
|--------|------|---------|-------------|
|
61
|
+
| `auto_process` | Boolean | `true` | Automatically process messages when published |
|
62
|
+
| `max_messages` | Integer | `1000` | Maximum messages to store (prevents memory overflow) |
|
63
|
+
|
64
|
+
## Usage Examples
|
65
|
+
|
66
|
+
### Basic Message Processing
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
# Create transport
|
70
|
+
transport = SmartMessage::Transport::MemoryTransport.new
|
71
|
+
|
72
|
+
# Define message
|
73
|
+
class AlertMessage < SmartMessage::Base
|
74
|
+
property :message, required: true
|
75
|
+
property :severity, default: 'info'
|
76
|
+
|
77
|
+
transport transport
|
78
|
+
|
79
|
+
def process
|
80
|
+
puts "[#{severity.upcase}] #{message}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Publish message
|
85
|
+
AlertMessage.new(
|
86
|
+
message: "System startup complete",
|
87
|
+
severity: "info"
|
88
|
+
).publish
|
89
|
+
|
90
|
+
# Output: [INFO] System startup complete
|
91
|
+
```
|
92
|
+
|
93
|
+
### Manual Processing Control
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
# Disable auto-processing for batch operations
|
97
|
+
transport = SmartMessage::Transport::MemoryTransport.new(auto_process: false)
|
98
|
+
|
99
|
+
class DataMessage < SmartMessage::Base
|
100
|
+
property :data
|
101
|
+
transport transport
|
102
|
+
|
103
|
+
def process
|
104
|
+
puts "Processing: #{data}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Publish multiple messages
|
109
|
+
DataMessage.new(data: "batch 1").publish
|
110
|
+
DataMessage.new(data: "batch 2").publish
|
111
|
+
DataMessage.new(data: "batch 3").publish
|
112
|
+
|
113
|
+
puts "Messages stored: #{transport.message_count}"
|
114
|
+
# Output: Messages stored: 3
|
115
|
+
|
116
|
+
# Process all at once
|
117
|
+
transport.process_all
|
118
|
+
# Output:
|
119
|
+
# Processing: batch 1
|
120
|
+
# Processing: batch 2
|
121
|
+
# Processing: batch 3
|
122
|
+
```
|
123
|
+
|
124
|
+
### Message Inspection
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
transport = SmartMessage::Transport::MemoryTransport.new(auto_process: false)
|
128
|
+
|
129
|
+
class OrderMessage < SmartMessage::Base
|
130
|
+
property :order_id, required: true
|
131
|
+
property :amount, required: true
|
132
|
+
transport transport
|
133
|
+
end
|
134
|
+
|
135
|
+
# Publish test messages
|
136
|
+
OrderMessage.new(order_id: "ORD-001", amount: 99.99).publish
|
137
|
+
OrderMessage.new(order_id: "ORD-002", amount: 149.50).publish
|
138
|
+
|
139
|
+
# Inspect stored messages
|
140
|
+
puts "Total messages: #{transport.message_count}"
|
141
|
+
transport.all_messages.each_with_index do |msg, index|
|
142
|
+
puts "Message #{index + 1}: #{msg[:message_class]} at #{msg[:published_at]}"
|
143
|
+
end
|
144
|
+
|
145
|
+
# Clear messages when done
|
146
|
+
transport.clear_messages
|
147
|
+
puts "Messages after clear: #{transport.message_count}"
|
148
|
+
```
|
149
|
+
|
150
|
+
## API Reference
|
151
|
+
|
152
|
+
### Instance Methods
|
153
|
+
|
154
|
+
#### `#message_count`
|
155
|
+
Returns the number of messages currently stored.
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
count = transport.message_count
|
159
|
+
puts "Stored messages: #{count}"
|
160
|
+
```
|
161
|
+
|
162
|
+
#### `#all_messages`
|
163
|
+
Returns a copy of all stored messages with metadata.
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
messages = transport.all_messages
|
167
|
+
messages.each do |msg|
|
168
|
+
puts "Class: #{msg[:message_class]}"
|
169
|
+
puts "Time: #{msg[:published_at]}"
|
170
|
+
puts "Data: #{msg[:serialized_message]}"
|
171
|
+
end
|
172
|
+
```
|
173
|
+
|
174
|
+
#### `#clear_messages`
|
175
|
+
Removes all stored messages from memory.
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
transport.clear_messages
|
179
|
+
```
|
180
|
+
|
181
|
+
#### `#process_all`
|
182
|
+
Manually processes all stored messages (useful when `auto_process: false`).
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
# Publish messages without auto-processing
|
186
|
+
transport = SmartMessage::Transport::MemoryTransport.new(auto_process: false)
|
187
|
+
# ... publish messages ...
|
188
|
+
|
189
|
+
# Process them all at once
|
190
|
+
transport.process_all
|
191
|
+
```
|
192
|
+
|
193
|
+
#### `#connected?`
|
194
|
+
Always returns `true` since memory transport is always available.
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
puts transport.connected? # => true
|
198
|
+
```
|
199
|
+
|
200
|
+
## Use Cases
|
201
|
+
|
202
|
+
### Unit Testing
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
RSpec.describe "Message Processing" do
|
206
|
+
let(:transport) { SmartMessage::Transport::MemoryTransport.new }
|
207
|
+
|
208
|
+
before do
|
209
|
+
MyMessage.transport = transport
|
210
|
+
transport.clear_messages
|
211
|
+
end
|
212
|
+
|
213
|
+
it "processes messages correctly" do
|
214
|
+
MyMessage.new(data: "test").publish
|
215
|
+
expect(transport.message_count).to eq(1)
|
216
|
+
end
|
217
|
+
|
218
|
+
it "respects message limits" do
|
219
|
+
transport = SmartMessage::Transport::MemoryTransport.new(max_messages: 2)
|
220
|
+
|
221
|
+
3.times { |i| MyMessage.new(data: i).publish }
|
222
|
+
expect(transport.message_count).to eq(2) # Oldest message dropped
|
223
|
+
end
|
224
|
+
end
|
225
|
+
```
|
226
|
+
|
227
|
+
### Development Environment
|
228
|
+
|
229
|
+
```ruby
|
230
|
+
# config/environments/development.rb
|
231
|
+
SmartMessage.configure do |config|
|
232
|
+
config.default_transport = SmartMessage::Transport::MemoryTransport.new(
|
233
|
+
auto_process: true,
|
234
|
+
max_messages: 500
|
235
|
+
)
|
236
|
+
config.logger.level = Logger::DEBUG # See all message activity
|
237
|
+
end
|
238
|
+
```
|
239
|
+
|
240
|
+
### Batch Processing
|
241
|
+
|
242
|
+
```ruby
|
243
|
+
# Collect messages for batch processing
|
244
|
+
transport = SmartMessage::Transport::MemoryTransport.new(auto_process: false)
|
245
|
+
|
246
|
+
# Publish work items
|
247
|
+
work_items.each do |item|
|
248
|
+
WorkMessage.new(item: item).publish
|
249
|
+
end
|
250
|
+
|
251
|
+
# Process batch when ready
|
252
|
+
puts "Processing #{transport.message_count} work items..."
|
253
|
+
start_time = Time.now
|
254
|
+
transport.process_all
|
255
|
+
puts "Completed in #{Time.now - start_time} seconds"
|
256
|
+
```
|
257
|
+
|
258
|
+
## Performance Characteristics
|
259
|
+
|
260
|
+
- **Latency**: ~0.01ms (memory access)
|
261
|
+
- **Throughput**: 100K+ messages/second
|
262
|
+
- **Memory Usage**: ~1KB per stored message
|
263
|
+
- **Concurrency**: Thread-safe with mutex protection
|
264
|
+
- **Persistence**: None (messages lost when process ends)
|
265
|
+
|
266
|
+
## Best Practices
|
267
|
+
|
268
|
+
### Testing
|
269
|
+
- Use `clear_messages` in test setup/teardown
|
270
|
+
- Set reasonable `max_messages` limits for long-running tests
|
271
|
+
- Disable `auto_process` for message inspection tests
|
272
|
+
|
273
|
+
### Development
|
274
|
+
- Enable debug logging to see message flow
|
275
|
+
- Use message inspection methods for debugging
|
276
|
+
- Consider memory limits in long-running development processes
|
277
|
+
|
278
|
+
### Production
|
279
|
+
⚠️ **Not recommended for production use**
|
280
|
+
- Messages are lost when process restarts
|
281
|
+
- No persistence or durability guarantees
|
282
|
+
- Limited by process memory
|
283
|
+
|
284
|
+
## Thread Safety
|
285
|
+
|
286
|
+
The Memory Transport is fully thread-safe:
|
287
|
+
- All operations use mutex synchronization
|
288
|
+
- Messages can be published from multiple threads
|
289
|
+
- Inspection methods return safe copies
|
290
|
+
|
291
|
+
```ruby
|
292
|
+
# Thread-safe concurrent publishing
|
293
|
+
threads = []
|
294
|
+
10.times do |i|
|
295
|
+
threads << Thread.new do
|
296
|
+
100.times { |j| TestMessage.new(data: "#{i}-#{j}").publish }
|
297
|
+
end
|
298
|
+
end
|
299
|
+
threads.each(&:join)
|
300
|
+
|
301
|
+
puts "Total messages: #{transport.message_count}" # Always accurate
|
302
|
+
```
|
303
|
+
|
304
|
+
## Migration from Memory Transport
|
305
|
+
|
306
|
+
When moving from Memory Transport to production transports:
|
307
|
+
|
308
|
+
```ruby
|
309
|
+
# Development (Memory Transport)
|
310
|
+
SmartMessage.configure do |config|
|
311
|
+
config.default_transport = SmartMessage::Transport::MemoryTransport.new
|
312
|
+
end
|
313
|
+
|
314
|
+
# Production (Redis Transport)
|
315
|
+
SmartMessage.configure do |config|
|
316
|
+
config.default_transport = SmartMessage::Transport::RedisTransport.new(
|
317
|
+
url: ENV['REDIS_URL']
|
318
|
+
)
|
319
|
+
end
|
320
|
+
```
|
321
|
+
|
322
|
+
Messages and processing logic remain identical - only the transport configuration changes.
|
323
|
+
|
324
|
+
## Examples
|
325
|
+
|
326
|
+
The `examples/memory/` directory contains comprehensive, runnable examples demonstrating Memory Transport capabilities:
|
327
|
+
|
328
|
+
### Core Messaging Examples
|
329
|
+
- **[03_point_to_point_orders.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/03_point_to_point_orders.rb)** - Point-to-point order processing with payment integration
|
330
|
+
- **[04_publish_subscribe_events.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/04_publish_subscribe_events.rb)** - Event broadcasting to multiple services (email, SMS, audit)
|
331
|
+
- **[05_many_to_many_chat.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/05_many_to_many_chat.rb)** - Interactive chat system with rooms, bots, and human agents
|
332
|
+
|
333
|
+
### Advanced Features
|
334
|
+
- **[01_message_deduplication_demo.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/01_message_deduplication_demo.rb)** - Message deduplication patterns and strategies
|
335
|
+
- **[02_dead_letter_queue_demo.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/02_dead_letter_queue_demo.rb)** - Complete Dead Letter Queue system with circuit breakers
|
336
|
+
- **[07_proc_handlers_demo.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/07_proc_handlers_demo.rb)** - Flexible message handlers (blocks, procs, lambdas, methods)
|
337
|
+
|
338
|
+
### Configuration & Monitoring
|
339
|
+
- **[08_custom_logger_demo.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/08_custom_logger_demo.rb)** - Advanced logging with SmartMessage::Logger::Default
|
340
|
+
- **[09_error_handling_demo.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/09_error_handling_demo.rb)** - Comprehensive validation, version mismatch, and error handling
|
341
|
+
- **[13_header_block_configuration.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/13_header_block_configuration.rb)** - Header and block configuration examples
|
342
|
+
- **[14_global_configuration_demo.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/14_global_configuration_demo.rb)** - Global configuration management
|
343
|
+
- **[15_logger_demo.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/15_logger_demo.rb)** - Advanced logging demonstrations
|
344
|
+
|
345
|
+
### Entity Addressing & Filtering
|
346
|
+
- **[10_entity_addressing_basic.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/10_entity_addressing_basic.rb)** - Basic FROM/TO/REPLY_TO message addressing
|
347
|
+
- **[11_entity_addressing_with_filtering.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/11_entity_addressing_with_filtering.rb)** - Advanced entity-aware message filtering
|
348
|
+
- **[12_regex_filtering_microservices.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/12_regex_filtering_microservices.rb)** - Advanced regex filtering for microservices
|
349
|
+
|
350
|
+
### Visual Demonstrations
|
351
|
+
- **[06_pretty_print_demo.rb](https://github.com/MadBomber/smart_message/blob/main/examples/memory/06_pretty_print_demo.rb)** - Message inspection and pretty-printing capabilities
|
352
|
+
|
353
|
+
### Running Examples
|
354
|
+
|
355
|
+
```bash
|
356
|
+
# Navigate to the SmartMessage directory
|
357
|
+
cd smart_message
|
358
|
+
|
359
|
+
# Run any Memory Transport example
|
360
|
+
ruby examples/memory/03_point_to_point_orders.rb
|
361
|
+
ruby examples/memory/05_many_to_many_chat.rb
|
362
|
+
ruby examples/memory/02_dead_letter_queue_demo.rb
|
363
|
+
|
364
|
+
# Or explore the entire directory
|
365
|
+
ls examples/memory/
|
366
|
+
```
|
367
|
+
|
368
|
+
Each example is self-contained and demonstrates specific Memory Transport features with clear educational comments and real-world scenarios.
|
369
|
+
|
370
|
+
## Related Documentation
|
371
|
+
|
372
|
+
- [Transport Overview](../reference/transports.md) - All available transports
|
373
|
+
- [Redis Transport](redis-transport.md) - Production-ready Redis transport
|
374
|
+
- [Testing Guide](../development/troubleshooting.md) - Testing strategies with SmartMessage
|