smart_message 0.0.10 → 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 +30 -0
- data/Gemfile.lock +35 -4
- data/README.md +169 -71
- 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} +78 -138
- 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/{message_deduplication.md → reference/message-deduplication.md} +1 -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/{10_message_deduplication.rb → memory/01_message_deduplication_demo.rb} +1 -1
- 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 +0 -2
- data/lib/smart_message/configuration.rb +1 -1
- 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/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 +170 -44
- 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
@@ -0,0 +1,509 @@
|
|
1
|
+
# Redis Transport
|
2
|
+
|
3
|
+
The **Redis Transport** is the foundational Redis-based transport implementation for SmartMessage. It uses Redis pub/sub channels for message distribution and provides reliable, high-performance messaging with minimal setup.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
Redis Transport is perfect for:
|
8
|
+
- **Simple pub/sub scenarios** - Basic message broadcasting
|
9
|
+
- **Development and testing** - Quick Redis-based messaging
|
10
|
+
- **Legacy compatibility** - Original SmartMessage Redis implementation
|
11
|
+
- **High performance** - Direct Redis pub/sub with minimal overhead
|
12
|
+
|
13
|
+
## Key Features
|
14
|
+
|
15
|
+
- 🚀 **Direct Redis Pub/Sub** - Uses native Redis PUBLISH/SUBSCRIBE
|
16
|
+
- ⚡ **High Performance** - ~1ms latency, 80K+ messages/second
|
17
|
+
- 🔄 **Auto-Reconnection** - Automatic Redis connection recovery
|
18
|
+
- 🧵 **Thread-Based Subscribers** - Traditional thread-per-subscriber model
|
19
|
+
- 🏷️ **Simple Channel Names** - Uses message class name as channel
|
20
|
+
- 📡 **Broadcast Delivery** - All subscribers receive all messages
|
21
|
+
|
22
|
+
## Architecture
|
23
|
+
|
24
|
+
```
|
25
|
+
Publisher → Redis Channel → All Subscribers
|
26
|
+
(class name) (thread-based)
|
27
|
+
```
|
28
|
+
|
29
|
+
The Redis Transport uses the message class name directly as the Redis channel name. For example, `OrderMessage` publishes to the `OrderMessage` channel.
|
30
|
+
|
31
|
+
## Configuration
|
32
|
+
|
33
|
+
### Basic Setup
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
# Minimal configuration
|
37
|
+
transport = SmartMessage::Transport::RedisTransport.new
|
38
|
+
|
39
|
+
# With Redis URL
|
40
|
+
transport = SmartMessage::Transport::RedisTransport.new(
|
41
|
+
url: 'redis://localhost:6379'
|
42
|
+
)
|
43
|
+
|
44
|
+
# Full configuration
|
45
|
+
transport = SmartMessage::Transport::RedisTransport.new(
|
46
|
+
url: 'redis://redis.example.com:6379',
|
47
|
+
db: 1,
|
48
|
+
auto_subscribe: true,
|
49
|
+
reconnect_attempts: 5,
|
50
|
+
reconnect_delay: 2
|
51
|
+
)
|
52
|
+
```
|
53
|
+
|
54
|
+
### Using with SmartMessage
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
# Configure as default transport
|
58
|
+
SmartMessage.configure do |config|
|
59
|
+
config.default_transport = SmartMessage::Transport::RedisTransport.new(
|
60
|
+
url: ENV['REDIS_URL'] || 'redis://localhost:6379'
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Use in message class
|
65
|
+
class OrderMessage < SmartMessage::Base
|
66
|
+
property :order_id, required: true
|
67
|
+
property :customer_email, required: true
|
68
|
+
|
69
|
+
transport :redis
|
70
|
+
|
71
|
+
def process
|
72
|
+
puts "Processing order: #{order_id} for #{customer_email}"
|
73
|
+
# Business logic here
|
74
|
+
end
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
## Configuration Options
|
79
|
+
|
80
|
+
| Option | Type | Default | Description |
|
81
|
+
|--------|------|---------|-------------|
|
82
|
+
| `url` | String | `redis://localhost:6379` | Redis connection URL |
|
83
|
+
| `db` | Integer | `0` | Redis database number |
|
84
|
+
| `auto_subscribe` | Boolean | `true` | Automatically start subscriber thread |
|
85
|
+
| `reconnect_attempts` | Integer | `5` | Number of reconnection attempts |
|
86
|
+
| `reconnect_delay` | Integer | `1` | Seconds between reconnection attempts |
|
87
|
+
|
88
|
+
## Usage Examples
|
89
|
+
|
90
|
+
### Basic Message Processing
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
# Define message
|
94
|
+
class UserNotification < SmartMessage::Base
|
95
|
+
property :user_id, required: true
|
96
|
+
property :message, required: true
|
97
|
+
property :type, default: 'info'
|
98
|
+
|
99
|
+
def process
|
100
|
+
user = User.find(user_id)
|
101
|
+
user.notifications.create!(
|
102
|
+
message: message,
|
103
|
+
type: type
|
104
|
+
)
|
105
|
+
puts "Notification sent to user #{user_id}: #{message}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Publish notification
|
110
|
+
UserNotification.new(
|
111
|
+
user_id: 123,
|
112
|
+
message: "Your order has been shipped!",
|
113
|
+
type: "success"
|
114
|
+
).publish
|
115
|
+
|
116
|
+
# Output: Notification sent to user 123: Your order has been shipped!
|
117
|
+
```
|
118
|
+
|
119
|
+
### Multiple Publishers and Subscribers
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
# Publisher 1 (Web Application)
|
123
|
+
class OrderCreated < SmartMessage::Base
|
124
|
+
property :order_id, required: true
|
125
|
+
property :user_id, required: true
|
126
|
+
property :total, required: true
|
127
|
+
|
128
|
+
def process
|
129
|
+
# This runs on all subscribers
|
130
|
+
puts "Order #{order_id} created for user #{user_id}: $#{total}"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Publisher 2 (Admin Panel)
|
135
|
+
class OrderCancelled < SmartMessage::Base
|
136
|
+
property :order_id, required: true
|
137
|
+
property :reason, required: true
|
138
|
+
|
139
|
+
def process
|
140
|
+
puts "Order #{order_id} cancelled: #{reason}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Both services will receive both message types
|
145
|
+
# All subscribers get all messages - broadcast behavior
|
146
|
+
|
147
|
+
# Publish from web app
|
148
|
+
OrderCreated.new(
|
149
|
+
order_id: "ORD-001",
|
150
|
+
user_id: 456,
|
151
|
+
total: 99.99
|
152
|
+
).publish
|
153
|
+
|
154
|
+
# Publish from admin panel
|
155
|
+
OrderCancelled.new(
|
156
|
+
order_id: "ORD-002",
|
157
|
+
reason: "Customer request"
|
158
|
+
).publish
|
159
|
+
```
|
160
|
+
|
161
|
+
### Connection Management
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
# Check connection status
|
165
|
+
transport = SmartMessage::Transport::RedisTransport.new
|
166
|
+
puts "Connected: #{transport.connected?}"
|
167
|
+
|
168
|
+
# Manual connection control
|
169
|
+
transport.stop_subscriber
|
170
|
+
transport.start_subscriber
|
171
|
+
|
172
|
+
# Access Redis connections directly
|
173
|
+
pub_redis = transport.redis_pub
|
174
|
+
sub_redis = transport.redis_sub
|
175
|
+
|
176
|
+
# Test connection
|
177
|
+
begin
|
178
|
+
pub_redis.ping
|
179
|
+
puts "Redis connection healthy"
|
180
|
+
rescue Redis::ConnectionError
|
181
|
+
puts "Redis connection failed"
|
182
|
+
end
|
183
|
+
```
|
184
|
+
|
185
|
+
### Error Handling
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
class ReliableMessage < SmartMessage::Base
|
189
|
+
property :data, required: true
|
190
|
+
|
191
|
+
def process
|
192
|
+
begin
|
193
|
+
# Potentially failing operation
|
194
|
+
external_api_call(data)
|
195
|
+
rescue => e
|
196
|
+
logger.error "Failed to process message: #{e.message}"
|
197
|
+
# Message processing failed, but won't retry
|
198
|
+
# Use dead letter queue for failed messages
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def external_api_call(data)
|
205
|
+
# Simulate external API call
|
206
|
+
raise "API unavailable" if rand < 0.1
|
207
|
+
puts "Processed: #{data}"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Publish messages - some may fail processing
|
212
|
+
10.times do |i|
|
213
|
+
ReliableMessage.new(data: "item-#{i}").publish
|
214
|
+
end
|
215
|
+
```
|
216
|
+
|
217
|
+
## Performance Characteristics
|
218
|
+
|
219
|
+
- **Latency**: ~1ms average message delivery
|
220
|
+
- **Throughput**: 80,000+ messages/second
|
221
|
+
- **Memory per Subscriber**: ~1MB baseline
|
222
|
+
- **Concurrent Subscribers**: ~200 practical limit
|
223
|
+
- **Connection Overhead**: 2 Redis connections (pub + sub)
|
224
|
+
- **Message Persistence**: None (fire-and-forget)
|
225
|
+
- **Message Ordering**: No guarantees
|
226
|
+
|
227
|
+
## API Reference
|
228
|
+
|
229
|
+
### Instance Methods
|
230
|
+
|
231
|
+
#### `#connected?`
|
232
|
+
Checks if Redis connections are healthy.
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
if transport.connected?
|
236
|
+
puts "Redis transport ready"
|
237
|
+
else
|
238
|
+
puts "Redis transport offline"
|
239
|
+
end
|
240
|
+
```
|
241
|
+
|
242
|
+
#### `#start_subscriber`
|
243
|
+
Manually starts the subscriber thread (if `auto_subscribe: false`).
|
244
|
+
|
245
|
+
```ruby
|
246
|
+
transport = SmartMessage::Transport::RedisTransport.new(auto_subscribe: false)
|
247
|
+
# ... do setup ...
|
248
|
+
transport.start_subscriber
|
249
|
+
```
|
250
|
+
|
251
|
+
#### `#stop_subscriber`
|
252
|
+
Stops the subscriber thread gracefully.
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
transport.stop_subscriber
|
256
|
+
puts "Subscriber stopped"
|
257
|
+
```
|
258
|
+
|
259
|
+
#### `#subscriber_running?`
|
260
|
+
Checks if the subscriber thread is active.
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
if transport.subscriber_running?
|
264
|
+
puts "Actively listening for messages"
|
265
|
+
end
|
266
|
+
```
|
267
|
+
|
268
|
+
## Channel Naming
|
269
|
+
|
270
|
+
Redis Transport uses simple channel naming:
|
271
|
+
- **Message Class**: `OrderMessage`
|
272
|
+
- **Redis Channel**: `"OrderMessage"`
|
273
|
+
- **Subscription**: Exact channel name match
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
# These all use the "UserMessage" channel
|
277
|
+
class UserMessage < SmartMessage::Base
|
278
|
+
property :user_id
|
279
|
+
end
|
280
|
+
|
281
|
+
# Publishing
|
282
|
+
UserMessage.new(user_id: 123).publish
|
283
|
+
# → Publishes to Redis channel "UserMessage"
|
284
|
+
|
285
|
+
# Subscribing
|
286
|
+
UserMessage.subscribe
|
287
|
+
# → Subscribes to Redis channel "UserMessage"
|
288
|
+
```
|
289
|
+
|
290
|
+
## Use Cases
|
291
|
+
|
292
|
+
### Simple Applications
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
# Perfect for straightforward pub/sub needs
|
296
|
+
class SystemAlert < SmartMessage::Base
|
297
|
+
property :level, required: true
|
298
|
+
property :message, required: true
|
299
|
+
|
300
|
+
def process
|
301
|
+
case level
|
302
|
+
when 'critical'
|
303
|
+
send_pager_alert(message)
|
304
|
+
when 'warning'
|
305
|
+
log_warning(message)
|
306
|
+
else
|
307
|
+
log_info(message)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
SystemAlert.new(level: 'critical', message: 'Database offline').publish
|
313
|
+
```
|
314
|
+
|
315
|
+
### Development Environment
|
316
|
+
|
317
|
+
```ruby
|
318
|
+
# config/environments/development.rb
|
319
|
+
SmartMessage.configure do |config|
|
320
|
+
config.default_transport = SmartMessage::Transport::RedisTransport.new(
|
321
|
+
url: 'redis://localhost:6379',
|
322
|
+
db: 1 # Separate dev database
|
323
|
+
)
|
324
|
+
config.logger.level = Logger::DEBUG
|
325
|
+
end
|
326
|
+
```
|
327
|
+
|
328
|
+
### Legacy System Integration
|
329
|
+
|
330
|
+
```ruby
|
331
|
+
# Maintaining compatibility with existing Redis pub/sub systems
|
332
|
+
class LegacyEvent < SmartMessage::Base
|
333
|
+
property :event_type, required: true
|
334
|
+
property :payload, required: true
|
335
|
+
|
336
|
+
def process
|
337
|
+
# Process in SmartMessage format
|
338
|
+
LegacyEventProcessor.new(event_type, payload).process
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
# External systems can still publish to "LegacyEvent" channel
|
343
|
+
# SmartMessage will automatically process them
|
344
|
+
```
|
345
|
+
|
346
|
+
## Performance Tuning
|
347
|
+
|
348
|
+
### Connection Pooling
|
349
|
+
|
350
|
+
```ruby
|
351
|
+
# For high-throughput applications, consider connection pooling
|
352
|
+
require 'connection_pool'
|
353
|
+
|
354
|
+
redis_pool = ConnectionPool.new(size: 10) do
|
355
|
+
Redis.new(url: 'redis://localhost:6379')
|
356
|
+
end
|
357
|
+
|
358
|
+
# Use custom Redis instance
|
359
|
+
transport = SmartMessage::Transport::RedisTransport.new
|
360
|
+
transport.instance_variable_set(:@redis_pub, redis_pool.with { |r| r })
|
361
|
+
```
|
362
|
+
|
363
|
+
### Monitoring
|
364
|
+
|
365
|
+
```ruby
|
366
|
+
# Monitor Redis transport health
|
367
|
+
class HealthCheck
|
368
|
+
def self.redis_transport_status
|
369
|
+
transport = SmartMessage.configuration.default_transport
|
370
|
+
{
|
371
|
+
connected: transport.connected?,
|
372
|
+
subscriber_running: transport.subscriber_running?,
|
373
|
+
redis_info: transport.redis_pub.info
|
374
|
+
}
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
puts HealthCheck.redis_transport_status
|
379
|
+
```
|
380
|
+
|
381
|
+
## Best Practices
|
382
|
+
|
383
|
+
### Configuration
|
384
|
+
- Use environment variables for Redis URLs
|
385
|
+
- Set appropriate database numbers for different environments
|
386
|
+
- Configure reasonable reconnection settings
|
387
|
+
|
388
|
+
### Error Handling
|
389
|
+
- Implement proper error handling in message processing
|
390
|
+
- Use logging to track message failures
|
391
|
+
- Consider implementing dead letter queue pattern
|
392
|
+
|
393
|
+
### Monitoring
|
394
|
+
- Monitor Redis connection health
|
395
|
+
- Track message throughput and processing times
|
396
|
+
- Set up alerts for subscriber thread failures
|
397
|
+
|
398
|
+
### Testing
|
399
|
+
- Use separate Redis databases for testing
|
400
|
+
- Clear Redis data between tests
|
401
|
+
- Mock Redis for unit tests
|
402
|
+
|
403
|
+
## Limitations
|
404
|
+
|
405
|
+
### No Pattern Matching
|
406
|
+
Redis Transport requires exact channel name matches:
|
407
|
+
|
408
|
+
```ruby
|
409
|
+
# This works - exact match
|
410
|
+
OrderMessage.subscribe # Subscribes to "OrderMessage"
|
411
|
+
|
412
|
+
# This doesn't work - no wildcard support
|
413
|
+
# Can't subscribe to "Order*" or "*Message"
|
414
|
+
```
|
415
|
+
|
416
|
+
### No Message Persistence
|
417
|
+
Messages are lost if no subscribers are listening:
|
418
|
+
|
419
|
+
```ruby
|
420
|
+
# If no subscribers are running, this message is lost
|
421
|
+
OrderMessage.new(order_id: 'ORD-001').publish
|
422
|
+
```
|
423
|
+
|
424
|
+
### Broadcasting Only
|
425
|
+
All subscribers receive all messages:
|
426
|
+
|
427
|
+
```ruby
|
428
|
+
# If 3 services subscribe to OrderMessage,
|
429
|
+
# all 3 will process every OrderMessage
|
430
|
+
# No load balancing between subscribers
|
431
|
+
```
|
432
|
+
|
433
|
+
## Migration to Enhanced Transport
|
434
|
+
|
435
|
+
When you need advanced routing, consider upgrading to Enhanced Transport:
|
436
|
+
|
437
|
+
```ruby
|
438
|
+
# From Redis Transport
|
439
|
+
SmartMessage.configure do |config|
|
440
|
+
config.default_transport = SmartMessage::Transport::RedisTransport.new
|
441
|
+
end
|
442
|
+
|
443
|
+
# To Enhanced Transport (with backward compatibility)
|
444
|
+
SmartMessage.configure do |config|
|
445
|
+
config.default_transport = SmartMessage::Transport::RedisEnhancedTransport.new
|
446
|
+
end
|
447
|
+
|
448
|
+
# All existing messages continue to work
|
449
|
+
# New messages gain pattern-matching capabilities
|
450
|
+
```
|
451
|
+
|
452
|
+
## Examples
|
453
|
+
|
454
|
+
The `examples/redis/` directory contains production-ready examples demonstrating Redis Transport capabilities:
|
455
|
+
|
456
|
+
### IoT and Real-Time Messaging
|
457
|
+
- **[01_smart_home_iot_demo.rb](https://github.com/MadBomber/smart_message/blob/main/examples/redis/01_smart_home_iot_demo.rb)** - Complete smart home IoT system with Redis pub/sub
|
458
|
+
- Real-time sensor data publishing (temperature, motion, battery levels)
|
459
|
+
- Device command routing with prefix-based filtering
|
460
|
+
- Alert generation and dashboard monitoring
|
461
|
+
- Multi-process distributed architecture
|
462
|
+
|
463
|
+
### Key Features Demonstrated
|
464
|
+
|
465
|
+
The IoT example showcases all Redis Transport capabilities:
|
466
|
+
- **Direct Redis Pub/Sub** - High-performance message broadcasting
|
467
|
+
- **Channel-Based Routing** - Each message type uses dedicated channels
|
468
|
+
- **Device-Specific Filtering** - Commands routed by device ID prefixes
|
469
|
+
- **Real-Time Data Flow** - Continuous sensor data streaming
|
470
|
+
- **Multi-Process Communication** - Distributed system simulation
|
471
|
+
|
472
|
+
### Running Examples
|
473
|
+
|
474
|
+
```bash
|
475
|
+
# Prerequisites: Start Redis server
|
476
|
+
redis-server
|
477
|
+
|
478
|
+
# Navigate to the SmartMessage directory
|
479
|
+
cd smart_message
|
480
|
+
|
481
|
+
# Run the Redis Transport IoT demo
|
482
|
+
ruby examples/redis/01_smart_home_iot_demo.rb
|
483
|
+
|
484
|
+
# Monitor Redis channels during the demo
|
485
|
+
redis-cli MONITOR
|
486
|
+
```
|
487
|
+
|
488
|
+
### Example Architecture
|
489
|
+
|
490
|
+
The IoT demo creates a complete distributed system:
|
491
|
+
- **5 IoT processes** - Sensors publishing data every 3-5 seconds
|
492
|
+
- **Dashboard process** - Aggregating and displaying system status
|
493
|
+
- **Redis channels** - `SensorDataMessage`, `DeviceCommandMessage`, `AlertMessage`
|
494
|
+
- **Device filtering** - THERM-, CAM-, LOCK- prefix routing
|
495
|
+
|
496
|
+
Each example includes comprehensive logging and demonstrates production-ready patterns for Redis-based messaging systems.
|
497
|
+
|
498
|
+
### Additional Resources
|
499
|
+
|
500
|
+
For more Redis Transport examples and patterns, also see:
|
501
|
+
- **[Memory Transport Examples](../../examples/memory/)** - Can be adapted to Redis Transport by changing configuration
|
502
|
+
- **[Complete Documentation](https://github.com/MadBomber/smart_message/blob/main/examples/redis/smart_home_iot_dataflow.md)** - Detailed data flow analysis with SVG diagrams
|
503
|
+
|
504
|
+
## Related Documentation
|
505
|
+
|
506
|
+
- [Redis Enhanced Transport](redis-enhanced-transport.md) - Advanced routing with patterns
|
507
|
+
- [Redis Queue Transport](redis-queue-transport.md) - Persistent queues with load balancing
|
508
|
+
- [Transport Comparison](redis-transport-comparison.md) - Compare all Redis transports
|
509
|
+
- [Transport Overview](../reference/transports.md) - All available transports
|
data/examples/README.md
CHANGED
@@ -15,11 +15,19 @@ ruby 04_redis_smart_home_iot.rb
|
|
15
15
|
ruby 05_proc_handlers.rb
|
16
16
|
ruby 06_custom_logger_example.rb
|
17
17
|
ruby 07_error_handling_scenarios.rb
|
18
|
-
ruby
|
18
|
+
ruby 08_entity_addressing_basic.rb
|
19
|
+
ruby 08_entity_addressing_with_filtering.rb
|
20
|
+
ruby 09_dead_letter_queue_demo.rb
|
19
21
|
ruby 09_regex_filtering_microservices.rb
|
20
22
|
ruby 10_header_block_configuration.rb
|
23
|
+
ruby 10_message_deduplication.rb
|
21
24
|
ruby 11_global_configuration_example.rb
|
22
25
|
ruby show_logger.rb
|
26
|
+
|
27
|
+
# Multi-program city scenario demo
|
28
|
+
cd city_scenario
|
29
|
+
./start_demo.sh # Starts all city services
|
30
|
+
./stop_demo.sh # Stops all running services
|
23
31
|
```
|
24
32
|
|
25
33
|
## Examples Overview
|
@@ -208,7 +216,7 @@ NotificationMessage.subscribe("NotificationService.handle")
|
|
208
216
|
---
|
209
217
|
|
210
218
|
### 8. Entity Addressing System (Advanced Routing)
|
211
|
-
**
|
219
|
+
**Files:** `08_entity_addressing_basic.rb`, `08_entity_addressing_with_filtering.rb`
|
212
220
|
|
213
221
|
**Scenario:** Comprehensive demonstration of SmartMessage's entity addressing system showing point-to-point messaging, broadcast patterns, request-reply workflows, and gateway patterns.
|
214
222
|
|
@@ -272,10 +280,21 @@ payment.publish
|
|
272
280
|
|
273
281
|
---
|
274
282
|
|
275
|
-
###
|
276
|
-
**
|
283
|
+
### 9. Dead Letter Queue & Regex Filtering
|
284
|
+
**Files:** `09_dead_letter_queue_demo.rb`, `09_regex_filtering_microservices.rb`
|
285
|
+
|
286
|
+
**Dead Letter Queue Demo:** Demonstrates handling of undeliverable messages and failed processing scenarios.
|
287
|
+
|
288
|
+
**Regex Filtering:** Shows advanced message filtering using regular expressions for microservice routing patterns.
|
289
|
+
|
290
|
+
---
|
291
|
+
|
292
|
+
### 10. Header Block Configuration & Message Deduplication
|
293
|
+
**Files:** `10_header_block_configuration.rb`, `10_message_deduplication.rb`
|
277
294
|
|
278
|
-
**
|
295
|
+
**Header Block Configuration:** Comprehensive demonstration of SmartMessage's flexible header configuration options, showing three different methods for setting addressing fields.
|
296
|
+
|
297
|
+
**Message Deduplication:** Shows strategies for handling duplicate messages in distributed systems.
|
279
298
|
|
280
299
|
**Key Features:**
|
281
300
|
- Direct class methods for addressing configuration
|
@@ -544,6 +563,80 @@ end
|
|
544
563
|
|
545
564
|
---
|
546
565
|
|
566
|
+
### City Emergency Services Scenario (Multi-Service Demo)
|
567
|
+
**Directory:** `city_scenario/`
|
568
|
+
|
569
|
+
**Scenario:** Complete city emergency services simulation demonstrating complex multi-service messaging patterns with health monitoring, emergency dispatch, and coordinated response systems.
|
570
|
+
|
571
|
+
**Key Features:**
|
572
|
+
- Multiple independent services communicating through SmartMessage
|
573
|
+
- Emergency 911 dispatch center routing calls to appropriate departments
|
574
|
+
- Fire and Police departments responding to different emergency types
|
575
|
+
- Houses generating fire emergencies and banks triggering silent alarms
|
576
|
+
- Health monitoring system checking all services periodically
|
577
|
+
- Common mixins for shared functionality (logging, health monitoring)
|
578
|
+
- Redis-based transport for production-ready messaging
|
579
|
+
|
580
|
+
**Services Included:**
|
581
|
+
- `emergency_dispatch_center.rb` - 911 call center routing emergencies
|
582
|
+
- `fire_department.rb` - Responds to fires, medical, rescue, and hazmat calls
|
583
|
+
- `police_department.rb` - Handles crime, accidents, and silent alarms
|
584
|
+
- `health_department.rb` - Monitors health status of all city services
|
585
|
+
- `house.rb` - Simulates residential fire emergencies
|
586
|
+
- `local_bank.rb` - Triggers silent alarms for security incidents
|
587
|
+
- `citizen.rb` - Generates 911 emergency calls
|
588
|
+
|
589
|
+
**Messages Used:**
|
590
|
+
- `Emergency911Message` - 911 emergency calls with caller details
|
591
|
+
- `FireEmergencyMessage` - Fire-specific emergency notifications
|
592
|
+
- `FireDispatchMessage` - Fire department dispatch responses
|
593
|
+
- `SilentAlarmMessage` - Bank security alerts to police
|
594
|
+
- `PoliceDispatchMessage` - Police unit dispatch notifications
|
595
|
+
- `EmergencyResolvedMessage` - Incident resolution notifications
|
596
|
+
- `HealthCheckMessage` - Service health check broadcasts
|
597
|
+
- `HealthStatusMessage` - Service health status responses
|
598
|
+
|
599
|
+
**Common Modules:**
|
600
|
+
- `Common::HealthMonitor` - Standardized health monitoring for all services
|
601
|
+
- `Common::Logger` - Centralized logging configuration
|
602
|
+
|
603
|
+
**What You'll Learn:**
|
604
|
+
- Building complex multi-service systems with SmartMessage
|
605
|
+
- Emergency dispatch routing patterns
|
606
|
+
- Service health monitoring and status reporting
|
607
|
+
- Message filtering and selective subscription
|
608
|
+
- Production-ready Redis transport configuration
|
609
|
+
- Extracting common functionality into mixins
|
610
|
+
- Coordinated response patterns between services
|
611
|
+
- Real-time event simulation and processing
|
612
|
+
|
613
|
+
**Running the Demo:**
|
614
|
+
```bash
|
615
|
+
cd examples/city_scenario
|
616
|
+
|
617
|
+
# Start all services (opens multiple terminal windows)
|
618
|
+
./start_demo.sh
|
619
|
+
|
620
|
+
# Monitor Redis message flow (optional)
|
621
|
+
ruby redis_monitor.rb
|
622
|
+
|
623
|
+
# View Redis statistics (optional)
|
624
|
+
ruby redis_stats.rb
|
625
|
+
|
626
|
+
# Stop all services
|
627
|
+
./stop_demo.sh
|
628
|
+
```
|
629
|
+
|
630
|
+
**Architecture Highlights:**
|
631
|
+
- **Dispatch Routing**: 911 center analyzes calls and routes to appropriate departments
|
632
|
+
- **Service Specialization**: Each department handles specific emergency types
|
633
|
+
- **Broadcast Health Checks**: Health department monitors all services simultaneously
|
634
|
+
- **Selective Subscriptions**: Services only receive relevant messages using filters
|
635
|
+
- **Incident Lifecycle**: Complete tracking from emergency to resolution
|
636
|
+
- **Production Patterns**: Demonstrates patterns suitable for production systems
|
637
|
+
|
638
|
+
---
|
639
|
+
|
547
640
|
### Show Logger Demonstration
|
548
641
|
**File:** `show_logger.rb`
|
549
642
|
|