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,230 @@
|
|
1
|
+
# Redis Transport Examples
|
2
|
+
|
3
|
+
This directory contains demonstration programs that use SmartMessage's **Redis Transport** for distributed messaging. These examples show how to build scalable, multi-process applications using Redis pub/sub messaging.
|
4
|
+
|
5
|
+
## Transport Overview
|
6
|
+
|
7
|
+
The Redis Transport is ideal for:
|
8
|
+
- **Distributed applications** across multiple processes/servers
|
9
|
+
- **Real-time messaging** with Redis pub/sub
|
10
|
+
- **Scalable architectures** with horizontal scaling
|
11
|
+
- **Cross-service communication** in microservices
|
12
|
+
- **Event-driven systems** with reliable message delivery
|
13
|
+
|
14
|
+
Redis Transport uses Redis's publish/subscribe mechanism, where each message class gets its own Redis channel for efficient routing.
|
15
|
+
|
16
|
+
## Prerequisites
|
17
|
+
|
18
|
+
Before running these examples:
|
19
|
+
|
20
|
+
1. **Install Redis:**
|
21
|
+
```bash
|
22
|
+
# macOS
|
23
|
+
brew install redis
|
24
|
+
|
25
|
+
# Ubuntu/Debian
|
26
|
+
sudo apt install redis-server
|
27
|
+
|
28
|
+
# CentOS/RHEL
|
29
|
+
sudo yum install redis
|
30
|
+
```
|
31
|
+
|
32
|
+
2. **Start Redis server:**
|
33
|
+
```bash
|
34
|
+
redis-server
|
35
|
+
# Runs on localhost:6379 by default
|
36
|
+
```
|
37
|
+
|
38
|
+
3. **Install Redis gem:**
|
39
|
+
```bash
|
40
|
+
gem install redis
|
41
|
+
```
|
42
|
+
|
43
|
+
## Example Programs
|
44
|
+
|
45
|
+
### 🏠 01_smart_home_iot_demo.rb
|
46
|
+
**Demonstrates:** IoT device communication via Redis pub/sub
|
47
|
+
**Use Case:** Smart home automation system
|
48
|
+
**Key Features:**
|
49
|
+
- **Multiple device types**: Sensors, controllers, and dashboards
|
50
|
+
- **Real-time data streaming**: Temperature, security, and energy data
|
51
|
+
- **Automatic fallback**: Uses memory transport if Redis unavailable
|
52
|
+
- **Channel separation**: Each message type gets dedicated Redis channel
|
53
|
+
- **Concurrent processing**: Multiple devices publishing simultaneously
|
54
|
+
|
55
|
+
**Message Types:**
|
56
|
+
- `SensorDataMessage` → `SensorDataMessage` channel
|
57
|
+
- `DeviceCommandMessage` → `DeviceCommandMessage` channel
|
58
|
+
- `SecurityAlertMessage` → `SecurityAlertMessage` channel
|
59
|
+
- `SystemStatusMessage` → `SystemStatusMessage` channel
|
60
|
+
|
61
|
+
**Architecture:**
|
62
|
+
```
|
63
|
+
┌─────────────┐ Redis Pub/Sub ┌─────────────┐
|
64
|
+
│ Sensors │ ──────────────────► │ Controllers │
|
65
|
+
│ (Publishers)│ │(Subscribers)│
|
66
|
+
└─────────────┘ └─────────────┘
|
67
|
+
│ │
|
68
|
+
▼ ▼
|
69
|
+
┌─────────────────────────────────────────────────┐
|
70
|
+
│ Redis Server │
|
71
|
+
│ Channels: SensorDataMessage, │
|
72
|
+
│ DeviceCommandMessage, etc. │
|
73
|
+
└─────────────────────────────────────────────────┘
|
74
|
+
▲ ▲
|
75
|
+
│ │
|
76
|
+
┌─────────────┐ ┌─────────────┐
|
77
|
+
│ Dashboard │ │ Alerts │
|
78
|
+
│(Subscriber) │ │(Subscriber) │
|
79
|
+
└─────────────┘ └─────────────┘
|
80
|
+
```
|
81
|
+
|
82
|
+
**Running the Demo:**
|
83
|
+
```bash
|
84
|
+
cd examples/redis
|
85
|
+
ruby 01_smart_home_iot_demo.rb
|
86
|
+
```
|
87
|
+
|
88
|
+
**What You'll See:**
|
89
|
+
1. Device initialization and Redis connection
|
90
|
+
2. Real-time sensor data publishing
|
91
|
+
3. Automated device commands and responses
|
92
|
+
4. Security monitoring and alerts
|
93
|
+
5. System health reporting
|
94
|
+
|
95
|
+
**Redis Commands to Monitor:**
|
96
|
+
```bash
|
97
|
+
# Watch active channels
|
98
|
+
redis-cli PUBSUB CHANNELS
|
99
|
+
|
100
|
+
# Monitor all pub/sub activity
|
101
|
+
redis-cli MONITOR
|
102
|
+
|
103
|
+
# Subscribe to specific message type
|
104
|
+
redis-cli SUBSCRIBE SensorDataMessage
|
105
|
+
```
|
106
|
+
|
107
|
+
## Key Concepts Demonstrated
|
108
|
+
|
109
|
+
### 1. **Distributed Messaging**
|
110
|
+
- Messages published in one process are received by subscribers in other processes
|
111
|
+
- True distributed communication across multiple Ruby instances
|
112
|
+
|
113
|
+
### 2. **Channel-Based Routing**
|
114
|
+
- Each SmartMessage class automatically gets its own Redis channel
|
115
|
+
- Clean separation of message types for efficient filtering
|
116
|
+
|
117
|
+
### 3. **Automatic Scaling**
|
118
|
+
- Multiple subscribers can listen to the same channel
|
119
|
+
- Publishers and subscribers can be added/removed dynamically
|
120
|
+
|
121
|
+
### 4. **Real-Time Communication**
|
122
|
+
- Near-instantaneous message delivery via Redis pub/sub
|
123
|
+
- Perfect for time-sensitive applications like IoT monitoring
|
124
|
+
|
125
|
+
### 5. **Connection Management**
|
126
|
+
- Automatic Redis connection handling
|
127
|
+
- Graceful fallback to memory transport when Redis unavailable
|
128
|
+
|
129
|
+
## Redis Transport Configuration
|
130
|
+
|
131
|
+
Basic Redis transport setup:
|
132
|
+
```ruby
|
133
|
+
SmartMessage.configure do |config|
|
134
|
+
config.transport = SmartMessage::Transport.create(:redis,
|
135
|
+
url: 'redis://localhost:6379',
|
136
|
+
db: 1 # Optional: use specific Redis database
|
137
|
+
)
|
138
|
+
config.serializer = SmartMessage::Serializer::Json.new
|
139
|
+
end
|
140
|
+
```
|
141
|
+
|
142
|
+
Per-message class configuration:
|
143
|
+
```ruby
|
144
|
+
class MyMessage < SmartMessage::Base
|
145
|
+
config do
|
146
|
+
transport SmartMessage::Transport.create(:redis,
|
147
|
+
url: 'redis://localhost:6379',
|
148
|
+
db: 2
|
149
|
+
)
|
150
|
+
serializer SmartMessage::Serializer::Json.new
|
151
|
+
end
|
152
|
+
end
|
153
|
+
```
|
154
|
+
|
155
|
+
## Architecture Benefits
|
156
|
+
|
157
|
+
### **Scalability**
|
158
|
+
- Horizontal scaling by adding more publishers/subscribers
|
159
|
+
- Redis handles connection pooling and load distribution
|
160
|
+
|
161
|
+
### **Reliability**
|
162
|
+
- Redis provides persistent connections and automatic reconnection
|
163
|
+
- Message delivery confirmation through Redis pub/sub protocol
|
164
|
+
|
165
|
+
### **Performance**
|
166
|
+
- Redis is optimized for high-throughput messaging
|
167
|
+
- In-memory storage for minimal latency
|
168
|
+
|
169
|
+
### **Flexibility**
|
170
|
+
- Easy to add new message types (new channels)
|
171
|
+
- Subscribers can filter by message patterns
|
172
|
+
|
173
|
+
## Production Considerations
|
174
|
+
|
175
|
+
### **Redis Configuration**
|
176
|
+
```bash
|
177
|
+
# Recommended Redis settings for production
|
178
|
+
maxmemory-policy allkeys-lru
|
179
|
+
timeout 0
|
180
|
+
tcp-keepalive 60
|
181
|
+
maxclients 10000
|
182
|
+
```
|
183
|
+
|
184
|
+
### **Connection Pooling**
|
185
|
+
```ruby
|
186
|
+
# Use connection pooling for high-load applications
|
187
|
+
SmartMessage::Transport.create(:redis,
|
188
|
+
url: 'redis://localhost:6379',
|
189
|
+
pool: { size: 20, timeout: 5 }
|
190
|
+
)
|
191
|
+
```
|
192
|
+
|
193
|
+
### **Monitoring and Debugging**
|
194
|
+
```bash
|
195
|
+
# Monitor Redis performance
|
196
|
+
redis-cli INFO stats
|
197
|
+
redis-cli MONITOR | grep PUBLISH
|
198
|
+
redis-cli CLIENT LIST
|
199
|
+
```
|
200
|
+
|
201
|
+
## Testing Distributed Scenarios
|
202
|
+
|
203
|
+
Run multiple terminal sessions to test distributed messaging:
|
204
|
+
|
205
|
+
**Terminal 1 (Publisher):**
|
206
|
+
```ruby
|
207
|
+
# Create a publisher-only script
|
208
|
+
sensor = SmartHomeSensor.new('living-room')
|
209
|
+
loop do
|
210
|
+
sensor.publish_temperature_reading
|
211
|
+
sleep(2)
|
212
|
+
end
|
213
|
+
```
|
214
|
+
|
215
|
+
**Terminal 2 (Subscriber):**
|
216
|
+
```ruby
|
217
|
+
# Create a subscriber-only script
|
218
|
+
SensorDataMessage.subscribe
|
219
|
+
# Keep process alive to receive messages
|
220
|
+
sleep
|
221
|
+
```
|
222
|
+
|
223
|
+
## Next Steps
|
224
|
+
|
225
|
+
After mastering Redis Transport:
|
226
|
+
- **[Redis Queue Examples](../redis_queue/)** - For guaranteed message delivery
|
227
|
+
- **[Redis Enhanced Examples](../redis_enhanced/)** - For advanced Redis patterns
|
228
|
+
- **[Memory Examples](../memory/)** - For development and testing
|
229
|
+
|
230
|
+
The Redis transport provides the foundation for building production-ready, distributed SmartMessage applications.
|
@@ -0,0 +1,127 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<svg width="800" height="600" viewBox="0 0 800 600" xmlns="http://www.w3.org/2000/svg">
|
3
|
+
<defs>
|
4
|
+
<style>
|
5
|
+
.bg { fill: transparent; }
|
6
|
+
.trigger-group { fill: #2a1a1a; stroke: #ff4a4a; stroke-width: 2; rx: 8; }
|
7
|
+
.device-group { fill: #1a2a1a; stroke: #4aff4a; stroke-width: 2; rx: 8; }
|
8
|
+
.alert-group { fill: #1a1a2a; stroke: #4a9eff; stroke-width: 2; rx: 8; }
|
9
|
+
.dashboard-final { fill: #2a2a1a; stroke: #aa4aff; stroke-width: 2; rx: 8; }
|
10
|
+
.trigger { fill: #4a2a1a; stroke: #ffaa4a; stroke-width: 1; rx: 4; }
|
11
|
+
.device { fill: #2a3a2a; stroke: #4aff4a; stroke-width: 1; rx: 4; }
|
12
|
+
.alert { fill: #2a2a3a; stroke: #4a9eff; stroke-width: 1; rx: 4; }
|
13
|
+
.flow { stroke: #ffaa4a; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
|
14
|
+
.alert-flow { stroke: #4a9eff; stroke-width: 2; fill: none; marker-end: url(#arrowhead-blue); }
|
15
|
+
.dashboard-flow { stroke: #aa4aff; stroke-width: 3; fill: none; marker-end: url(#arrowhead-purple); }
|
16
|
+
.text { fill: #ffffff; font-family: 'Arial', sans-serif; font-size: 11px; }
|
17
|
+
.title { fill: #4a9eff; font-family: 'Arial', sans-serif; font-size: 18px; font-weight: bold; }
|
18
|
+
.subtitle { fill: #ffaa4a; font-family: 'Arial', sans-serif; font-size: 12px; }
|
19
|
+
.group-title { fill: #ffffff; font-family: 'Arial', sans-serif; font-size: 13px; font-weight: bold; }
|
20
|
+
</style>
|
21
|
+
<marker id="arrowhead" markerWidth="8" markerHeight="6"
|
22
|
+
refX="8" refY="3" orient="auto">
|
23
|
+
<polygon points="0 0, 8 3, 0 6" fill="#ffaa4a" />
|
24
|
+
</marker>
|
25
|
+
<marker id="arrowhead-blue" markerWidth="8" markerHeight="6"
|
26
|
+
refX="8" refY="3" orient="auto">
|
27
|
+
<polygon points="0 0, 8 3, 0 6" fill="#4a9eff" />
|
28
|
+
</marker>
|
29
|
+
<marker id="arrowhead-purple" markerWidth="8" markerHeight="6"
|
30
|
+
refX="8" refY="3" orient="auto">
|
31
|
+
<polygon points="0 0, 8 3, 0 6" fill="#aa4aff" />
|
32
|
+
</marker>
|
33
|
+
</defs>
|
34
|
+
|
35
|
+
<!-- Background -->
|
36
|
+
<rect class="bg" width="800" height="600"/>
|
37
|
+
|
38
|
+
<!-- Title -->
|
39
|
+
<text x="400" y="25" text-anchor="middle" class="title">Alert System Flow</text>
|
40
|
+
<text x="400" y="45" text-anchor="middle" class="subtitle">IoT Device Alert Generation and Processing</text>
|
41
|
+
|
42
|
+
<!-- Triggers Group -->
|
43
|
+
<rect x="50" y="80" width="200" height="180" class="trigger-group"/>
|
44
|
+
<text x="150" y="105" text-anchor="middle" class="group-title">Alert Triggers</text>
|
45
|
+
|
46
|
+
<rect x="70" y="120" width="160" height="30" class="trigger"/>
|
47
|
+
<text x="150" y="140" text-anchor="middle" class="text">High Temperature > 28°C</text>
|
48
|
+
|
49
|
+
<rect x="70" y="160" width="160" height="30" class="trigger"/>
|
50
|
+
<text x="150" y="180" text-anchor="middle" class="text">Motion Detected</text>
|
51
|
+
|
52
|
+
<rect x="70" y="200" width="160" height="30" class="trigger"/>
|
53
|
+
<text x="150" y="220" text-anchor="middle" class="text">Battery < 20%</text>
|
54
|
+
|
55
|
+
<rect x="70" y="240" width="160" height="30" class="trigger"/>
|
56
|
+
<text x="150" y="260" text-anchor="middle" class="text">Device Offline > 30s</text>
|
57
|
+
|
58
|
+
<!-- Devices Group -->
|
59
|
+
<rect x="300" y="80" width="200" height="180" class="device-group"/>
|
60
|
+
<text x="400" y="105" text-anchor="middle" class="group-title">IoT Devices</text>
|
61
|
+
|
62
|
+
<rect x="320" y="120" width="160" height="30" class="device"/>
|
63
|
+
<text x="400" y="140" text-anchor="middle" class="text">🌡️ Thermostat</text>
|
64
|
+
|
65
|
+
<rect x="320" y="160" width="160" height="30" class="device"/>
|
66
|
+
<text x="400" y="180" text-anchor="middle" class="text">📹 Camera</text>
|
67
|
+
|
68
|
+
<rect x="320" y="200" width="160" height="30" class="device"/>
|
69
|
+
<text x="400" y="220" text-anchor="middle" class="text">🚪 Door Lock</text>
|
70
|
+
|
71
|
+
<!-- Alert Channel Group -->
|
72
|
+
<rect x="550" y="80" width="200" height="180" class="alert-group"/>
|
73
|
+
<text x="650" y="105" text-anchor="middle" class="group-title">AlertMessage Channel</text>
|
74
|
+
|
75
|
+
<rect x="570" y="120" width="160" height="30" class="alert"/>
|
76
|
+
<text x="650" y="140" text-anchor="middle" class="text">Motion Alert</text>
|
77
|
+
|
78
|
+
<rect x="570" y="160" width="160" height="30" class="alert"/>
|
79
|
+
<text x="650" y="180" text-anchor="middle" class="text">High Temp Alert</text>
|
80
|
+
|
81
|
+
<rect x="570" y="200" width="160" height="30" class="alert"/>
|
82
|
+
<text x="650" y="220" text-anchor="middle" class="text">Battery Low Alert</text>
|
83
|
+
|
84
|
+
<rect x="570" y="240" width="160" height="30" class="alert"/>
|
85
|
+
<text x="650" y="260" text-anchor="middle" class="text">Device Offline Alert</text>
|
86
|
+
|
87
|
+
<!-- Dashboard -->
|
88
|
+
<rect x="300" y="320" width="200" height="60" class="dashboard-final"/>
|
89
|
+
<text x="400" y="345" text-anchor="middle" class="group-title">📊 Dashboard</text>
|
90
|
+
<text x="400" y="365" text-anchor="middle" class="text">Alert Processing & Display</text>
|
91
|
+
|
92
|
+
<!-- Flow arrows -->
|
93
|
+
<!-- Triggers to Devices -->
|
94
|
+
<path d="M 230 135 L 320 135" class="flow"/>
|
95
|
+
<path d="M 230 175 L 320 175" class="flow"/>
|
96
|
+
<path d="M 230 215 L 320 215" class="flow"/>
|
97
|
+
<path d="M 230 255 L 320 255" class="flow"/>
|
98
|
+
|
99
|
+
<!-- Devices to Alert Channel -->
|
100
|
+
<path d="M 480 135 L 570 175" class="alert-flow"/>
|
101
|
+
<path d="M 480 175 L 570 135" class="alert-flow"/>
|
102
|
+
<path d="M 480 215 L 570 215" class="alert-flow"/>
|
103
|
+
<path d="M 480 255 L 570 255" class="alert-flow"/>
|
104
|
+
|
105
|
+
<!-- Alert Channel to Dashboard -->
|
106
|
+
<path d="M 650 280 L 450 320" class="dashboard-flow"/>
|
107
|
+
|
108
|
+
<!-- Alert Processing Details -->
|
109
|
+
<rect x="50" y="420" width="700" height="160" fill="#1a1a1a" stroke="#4a9eff" rx="8"/>
|
110
|
+
<text x="70" y="445" class="title">Alert Processing Logic</text>
|
111
|
+
|
112
|
+
<text x="70" y="470" class="text">🌡️ Temperature Alerts:</text>
|
113
|
+
<text x="90" y="485" class="subtitle">• Thermostat monitors temperature every 3 seconds</text>
|
114
|
+
<text x="90" y="500" class="subtitle">• Alert triggered when temperature > 28°C for HVAC efficiency</text>
|
115
|
+
|
116
|
+
<text x="400" y="470" class="text">📹 Motion Alerts:</text>
|
117
|
+
<text x="420" y="485" class="subtitle">• Camera detects motion using built-in sensors</text>
|
118
|
+
<text x="420" y="500" class="subtitle">• Immediate alert published to AlertMessage channel</text>
|
119
|
+
|
120
|
+
<text x="70" y="525" class="text">🔋 Battery Alerts:</text>
|
121
|
+
<text x="90" y="540" class="subtitle">• All devices report battery level with sensor data</text>
|
122
|
+
<text x="90" y="555" class="subtitle">• Critical alert when battery drops below 20%</text>
|
123
|
+
|
124
|
+
<text x="400" y="525" class="text">⚠️ Offline Alerts:</text>
|
125
|
+
<text x="420" y="540" class="subtitle">• Dashboard tracks last seen timestamp for each device</text>
|
126
|
+
<text x="420" y="555" class="subtitle">• Alert generated if device silent for more than 30 seconds</text>
|
127
|
+
</svg>
|
@@ -0,0 +1,107 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<svg width="800" height="500" viewBox="0 0 800 500" xmlns="http://www.w3.org/2000/svg">
|
3
|
+
<defs>
|
4
|
+
<style>
|
5
|
+
.bg { fill: transparent; }
|
6
|
+
.data-group { fill: #1a2a1a; stroke: #4aff4a; stroke-width: 2; rx: 8; }
|
7
|
+
.process-group { fill: #2a1a2a; stroke: #aa4aff; stroke-width: 2; rx: 8; }
|
8
|
+
.output-group { fill: #2a2a1a; stroke: #ffaa4a; stroke-width: 2; rx: 8; }
|
9
|
+
.component { fill: #3a3a3a; stroke: #ffffff; stroke-width: 1; rx: 4; }
|
10
|
+
.flow { stroke: #4aff4a; stroke-width: 2; fill: none; marker-end: url(#arrowhead-green); }
|
11
|
+
.process-flow { stroke: #aa4aff; stroke-width: 2; fill: none; marker-end: url(#arrowhead-purple); }
|
12
|
+
.output-flow { stroke: #ffaa4a; stroke-width: 3; fill: none; marker-end: url(#arrowhead-orange); }
|
13
|
+
.text { fill: #ffffff; font-family: 'Arial', sans-serif; font-size: 11px; }
|
14
|
+
.title { fill: #4a9eff; font-family: 'Arial', sans-serif; font-size: 18px; font-weight: bold; }
|
15
|
+
.subtitle { fill: #ffaa4a; font-family: 'Arial', sans-serif; font-size: 12px; }
|
16
|
+
.group-title { fill: #ffffff; font-family: 'Arial', sans-serif; font-size: 13px; font-weight: bold; }
|
17
|
+
</style>
|
18
|
+
<marker id="arrowhead-green" markerWidth="8" markerHeight="6"
|
19
|
+
refX="8" refY="3" orient="auto">
|
20
|
+
<polygon points="0 0, 8 3, 0 6" fill="#4aff4a" />
|
21
|
+
</marker>
|
22
|
+
<marker id="arrowhead-purple" markerWidth="8" markerHeight="6"
|
23
|
+
refX="8" refY="3" orient="auto">
|
24
|
+
<polygon points="0 0, 8 3, 0 6" fill="#aa4aff" />
|
25
|
+
</marker>
|
26
|
+
<marker id="arrowhead-orange" markerWidth="8" markerHeight="6"
|
27
|
+
refX="8" refY="3" orient="auto">
|
28
|
+
<polygon points="0 0, 8 3, 0 6" fill="#ffaa4a" />
|
29
|
+
</marker>
|
30
|
+
</defs>
|
31
|
+
|
32
|
+
<!-- Background -->
|
33
|
+
<rect class="bg" width="800" height="500"/>
|
34
|
+
|
35
|
+
<!-- Title -->
|
36
|
+
<text x="400" y="25" text-anchor="middle" class="title">Dashboard Status Flow</text>
|
37
|
+
<text x="400" y="45" text-anchor="middle" class="subtitle">System Status Aggregation and Periodic Reporting</text>
|
38
|
+
|
39
|
+
<!-- Data Collection Group -->
|
40
|
+
<rect x="50" y="80" width="200" height="180" class="data-group"/>
|
41
|
+
<text x="150" y="105" text-anchor="middle" class="group-title">Data Collection</text>
|
42
|
+
|
43
|
+
<rect x="70" y="120" width="160" height="30" class="component"/>
|
44
|
+
<text x="150" y="140" text-anchor="middle" class="text">Device Last Seen Times</text>
|
45
|
+
|
46
|
+
<rect x="70" y="160" width="160" height="30" class="component"/>
|
47
|
+
<text x="150" y="180" text-anchor="middle" class="text">Alert Counts</text>
|
48
|
+
|
49
|
+
<rect x="70" y="200" width="160" height="30" class="component"/>
|
50
|
+
<text x="150" y="220" text-anchor="middle" class="text">Battery Levels</text>
|
51
|
+
|
52
|
+
<rect x="70" y="240" width="160" height="30" class="component"/>
|
53
|
+
<text x="150" y="260" text-anchor="middle" class="text">System Health</text>
|
54
|
+
|
55
|
+
<!-- Status Processing Group -->
|
56
|
+
<rect x="300" y="80" width="200" height="180" class="process-group"/>
|
57
|
+
<text x="400" y="105" text-anchor="middle" class="group-title">Status Processing</text>
|
58
|
+
|
59
|
+
<rect x="320" y="120" width="160" height="40" class="component"/>
|
60
|
+
<text x="400" y="140" text-anchor="middle" class="text">Count Active Devices</text>
|
61
|
+
<text x="400" y="155" text-anchor="middle" class="text">last_seen < 30s</text>
|
62
|
+
|
63
|
+
<rect x="320" y="170" width="160" height="40" class="component"/>
|
64
|
+
<text x="400" y="190" text-anchor="middle" class="text">Count Recent Alerts</text>
|
65
|
+
<text x="400" y="205" text-anchor="middle" class="text">last 5 minutes</text>
|
66
|
+
|
67
|
+
<rect x="320" y="220" width="160" height="30" class="component"/>
|
68
|
+
<text x="400" y="240" text-anchor="middle" class="text">Calculate Averages</text>
|
69
|
+
|
70
|
+
<!-- Status Output Group -->
|
71
|
+
<rect x="550" y="80" width="200" height="180" class="output-group"/>
|
72
|
+
<text x="650" y="105" text-anchor="middle" class="group-title">Status Output</text>
|
73
|
+
|
74
|
+
<rect x="570" y="140" width="160" height="60" class="component"/>
|
75
|
+
<text x="650" y="165" text-anchor="middle" class="text">DashboardStatusMessage</text>
|
76
|
+
<text x="650" y="185" text-anchor="middle" class="text">Every 10 seconds</text>
|
77
|
+
|
78
|
+
<!-- Flow arrows -->
|
79
|
+
<path d="M 250 150 L 300 140" class="flow"/>
|
80
|
+
<path d="M 250 180 L 300 190" class="flow"/>
|
81
|
+
<path d="M 250 210 L 300 235" class="flow"/>
|
82
|
+
<path d="M 250 240 L 300 235" class="flow"/>
|
83
|
+
|
84
|
+
<path d="M 500 140 L 550 170" class="process-flow"/>
|
85
|
+
<path d="M 500 190 L 550 170" class="process-flow"/>
|
86
|
+
<path d="M 500 235 L 550 170" class="process-flow"/>
|
87
|
+
|
88
|
+
<!-- Status Message Details -->
|
89
|
+
<rect x="50" y="300" width="700" height="180" fill="#1a1a1a" stroke="#4a9eff" rx="8"/>
|
90
|
+
<text x="70" y="325" class="title">Dashboard Status Message Content</text>
|
91
|
+
|
92
|
+
<text x="70" y="350" class="text">📊 System Metrics (Updated every 10 seconds):</text>
|
93
|
+
<text x="90" y="365" class="subtitle">• Active device count: Devices that have reported within last 30 seconds</text>
|
94
|
+
<text x="90" y="380" class="subtitle">• Total alert count: Alerts generated in the last 5 minutes</text>
|
95
|
+
<text x="90" y="395" class="subtitle">• Average battery level: Calculated across all battery-powered devices</text>
|
96
|
+
<text x="90" y="410" class="subtitle">• System health score: Composite metric based on device availability</text>
|
97
|
+
|
98
|
+
<text x="400" y="350" class="text">🔄 Processing Logic:</text>
|
99
|
+
<text x="420" y="365" class="subtitle">• Device activity tracking: Timestamp comparison for online status</text>
|
100
|
+
<text x="420" y="380" class="subtitle">• Alert aggregation: Count and categorize alerts by severity</text>
|
101
|
+
<text x="420" y="395" class="subtitle">• Performance calculation: Battery levels, response times, error rates</text>
|
102
|
+
<text x="420" y="410" class="subtitle">• Status publication: Broadcast to all subscribers for system visibility</text>
|
103
|
+
|
104
|
+
<text x="70" y="440" class="text">📈 Status Message Format:</text>
|
105
|
+
<text x="90" y="455" class="subtitle">• device_count: 3, alert_count: 2, avg_battery: 78.5%, health_score: "good"</text>
|
106
|
+
<text x="90" y="470" class="subtitle">• Subscribers: Mobile apps, monitoring systems, other dashboards</text>
|
107
|
+
</svg>
|
@@ -0,0 +1,113 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<svg width="800" height="500" viewBox="0 0 800 500" xmlns="http://www.w3.org/2000/svg">
|
3
|
+
<defs>
|
4
|
+
<style>
|
5
|
+
.bg { fill: transparent; }
|
6
|
+
.app { fill: #2a1a3a; stroke: #aa4aff; stroke-width: 2; rx: 8; }
|
7
|
+
.redis { fill: #3a1a1a; stroke: #ff4a4a; stroke-width: 2; rx: 8; }
|
8
|
+
.thermostat { fill: #4a2a1a; stroke: #ff6b6b; stroke-width: 2; rx: 8; }
|
9
|
+
.camera { fill: #1a3a3a; stroke: #4ecdc4; stroke-width: 2; rx: 8; }
|
10
|
+
.lock { fill: #3a3a1a; stroke: #ffe66d; stroke-width: 2; rx: 8; }
|
11
|
+
.command { stroke: #aa4aff; stroke-width: 3; fill: none; marker-end: url(#arrowhead); }
|
12
|
+
.process { stroke: #4aff4a; stroke-width: 2; fill: none; marker-end: url(#arrowhead-green); }
|
13
|
+
.ignore { stroke: #ff4a4a; stroke-width: 2; fill: none; stroke-dasharray: 5,5; }
|
14
|
+
.text { fill: #ffffff; font-family: 'Arial', sans-serif; font-size: 12px; }
|
15
|
+
.title { fill: #4a9eff; font-family: 'Arial', sans-serif; font-size: 18px; font-weight: bold; }
|
16
|
+
.subtitle { fill: #ffaa4a; font-family: 'Arial', sans-serif; font-size: 11px; }
|
17
|
+
.note { fill: #aaaaaa; font-family: 'Arial', sans-serif; font-size: 10px; }
|
18
|
+
</style>
|
19
|
+
<marker id="arrowhead" markerWidth="8" markerHeight="6"
|
20
|
+
refX="8" refY="3" orient="auto">
|
21
|
+
<polygon points="0 0, 8 3, 0 6" fill="#aa4aff" />
|
22
|
+
</marker>
|
23
|
+
<marker id="arrowhead-green" markerWidth="8" markerHeight="6"
|
24
|
+
refX="8" refY="3" orient="auto">
|
25
|
+
<polygon points="0 0, 8 3, 0 6" fill="#4aff4a" />
|
26
|
+
</marker>
|
27
|
+
</defs>
|
28
|
+
|
29
|
+
<!-- Background -->
|
30
|
+
<rect class="bg" width="800" height="500"/>
|
31
|
+
|
32
|
+
<!-- Title -->
|
33
|
+
<text x="400" y="25" text-anchor="middle" class="title">Device Command Flow</text>
|
34
|
+
<text x="400" y="45" text-anchor="middle" class="subtitle">Device-Specific Command Routing via Redis Channel</text>
|
35
|
+
|
36
|
+
<!-- Participants -->
|
37
|
+
<rect x="50" y="80" width="120" height="60" class="app"/>
|
38
|
+
<text x="110" y="105" text-anchor="middle" class="text">📱 Mobile App</text>
|
39
|
+
<text x="110" y="125" text-anchor="middle" class="subtitle">User Interface</text>
|
40
|
+
|
41
|
+
<rect x="320" y="80" width="120" height="60" class="redis"/>
|
42
|
+
<text x="380" y="105" text-anchor="middle" class="text">Redis Channel</text>
|
43
|
+
<text x="380" y="125" text-anchor="middle" class="subtitle">DeviceCommandMessage</text>
|
44
|
+
|
45
|
+
<rect x="580" y="50" width="120" height="60" class="thermostat"/>
|
46
|
+
<text x="640" y="75" text-anchor="middle" class="text">🌡️ Thermostat</text>
|
47
|
+
<text x="640" y="95" text-anchor="middle" class="subtitle">THERM-001</text>
|
48
|
+
|
49
|
+
<rect x="580" y="130" width="120" height="60" class="camera"/>
|
50
|
+
<text x="640" y="155" text-anchor="middle" class="text">📹 Camera</text>
|
51
|
+
<text x="640" y="175" text-anchor="middle" class="subtitle">CAM-001</text>
|
52
|
+
|
53
|
+
<rect x="580" y="210" width="120" height="60" class="lock"/>
|
54
|
+
<text x="640" y="235" text-anchor="middle" class="text">🚪 Door Lock</text>
|
55
|
+
<text x="640" y="255" text-anchor="middle" class="subtitle">LOCK-001</text>
|
56
|
+
|
57
|
+
<!-- Vertical lifelines -->
|
58
|
+
<line x1="110" y1="140" x2="110" y2="400" stroke="#666" stroke-width="2" stroke-dasharray="3,3"/>
|
59
|
+
<line x1="380" y1="140" x2="380" y2="400" stroke="#666" stroke-width="2" stroke-dasharray="3,3"/>
|
60
|
+
<line x1="640" y1="110" x2="640" y2="400" stroke="#666" stroke-width="2" stroke-dasharray="3,3"/>
|
61
|
+
<line x1="640" y1="190" x2="640" y2="400" stroke="#666" stroke-width="2" stroke-dasharray="3,3"/>
|
62
|
+
<line x1="640" y1="270" x2="640" y2="400" stroke="#666" stroke-width="2" stroke-dasharray="3,3"/>
|
63
|
+
|
64
|
+
<!-- Command 1: Thermostat Command -->
|
65
|
+
<path d="M 110 170 L 380 170" class="command"/>
|
66
|
+
<text x="245" y="165" text-anchor="middle" class="text">DeviceCommandMessage</text>
|
67
|
+
<text x="245" y="185" text-anchor="middle" class="note">device_id: THERM-001, command: set_temperature</text>
|
68
|
+
|
69
|
+
<!-- Routing to devices -->
|
70
|
+
<path d="M 380 190 L 580 80" class="process"/>
|
71
|
+
<text x="480" y="135" text-anchor="middle" class="text">✅ Processes THERM prefix match</text>
|
72
|
+
|
73
|
+
<path d="M 380 190 L 580 160" class="ignore"/>
|
74
|
+
<text x="480" y="175" text-anchor="middle" class="text">❌ Ignores not CAM prefix</text>
|
75
|
+
|
76
|
+
<path d="M 380 190 L 580 240" class="ignore"/>
|
77
|
+
<text x="480" y="215" text-anchor="middle" class="text">❌ Ignores not LOCK prefix</text>
|
78
|
+
|
79
|
+
<!-- Command 2: Camera Command -->
|
80
|
+
<path d="M 110 280 L 380 280" class="command"/>
|
81
|
+
<text x="245" y="275" text-anchor="middle" class="text">DeviceCommandMessage</text>
|
82
|
+
<text x="245" y="295" text-anchor="middle" class="note">device_id: CAM-001, command: start_recording</text>
|
83
|
+
|
84
|
+
<!-- Routing to devices for command 2 -->
|
85
|
+
<path d="M 380 300 L 580 80" class="ignore"/>
|
86
|
+
<text x="480" y="285" text-anchor="middle" class="text">❌ Ignores not THERM prefix</text>
|
87
|
+
|
88
|
+
<path d="M 380 300 L 580 160" class="process"/>
|
89
|
+
<text x="480" y="305" text-anchor="middle" class="text">✅ Processes CAM prefix match</text>
|
90
|
+
|
91
|
+
<path d="M 380 300 L 580 240" class="ignore"/>
|
92
|
+
<text x="480" y="325" text-anchor="middle" class="text">❌ Ignores not LOCK prefix</text>
|
93
|
+
|
94
|
+
<!-- Device Command Filtering Rules -->
|
95
|
+
<rect x="50" y="320" width="700" height="160" fill="#1a1a1a" stroke="#4a9eff" rx="8"/>
|
96
|
+
<text x="70" y="345" class="title">Device Command Filtering Rules</text>
|
97
|
+
|
98
|
+
<text x="70" y="370" class="text">🌡️ THERM-* devices:</text>
|
99
|
+
<text x="90" y="385" class="subtitle">• Accept: set_temperature, get_status</text>
|
100
|
+
<text x="90" y="400" class="subtitle">• Filter: Only process commands with device_id starting with "THERM-"</text>
|
101
|
+
|
102
|
+
<text x="400" y="370" class="text">📹 CAM-* devices:</text>
|
103
|
+
<text x="420" y="385" class="subtitle">• Accept: start_recording, stop_recording, get_status</text>
|
104
|
+
<text x="420" y="400" class="subtitle">• Filter: Only process commands with device_id starting with "CAM-"</text>
|
105
|
+
|
106
|
+
<text x="70" y="425" class="text">🚪 LOCK-* devices:</text>
|
107
|
+
<text x="90" y="440" class="subtitle">• Accept: lock, unlock, get_status</text>
|
108
|
+
<text x="90" y="455" class="subtitle">• Filter: Only process commands with device_id starting with "LOCK-"</text>
|
109
|
+
|
110
|
+
<text x="400" y="425" class="text">📊 Architecture Benefits:</text>
|
111
|
+
<text x="420" y="440" class="subtitle">• Efficient: Devices ignore irrelevant commands automatically</text>
|
112
|
+
<text x="420" y="455" class="subtitle">• Scalable: Easy to add new device types with new prefixes</text>
|
113
|
+
</svg>
|