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,587 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# examples/redis_queue/07_queue_management.rb
|
3
|
+
# Queue management, monitoring and administration with Redis Queue Transport
|
4
|
+
|
5
|
+
require_relative '../../lib/smart_message'
|
6
|
+
|
7
|
+
puts "📊 Redis Queue Transport - Queue Management & Monitoring Demo"
|
8
|
+
puts "=" * 65
|
9
|
+
|
10
|
+
#==============================================================================
|
11
|
+
# Management Transport Setup
|
12
|
+
#==============================================================================
|
13
|
+
|
14
|
+
# Create transport instance for queue management
|
15
|
+
mgmt_transport = SmartMessage::Transport::RedisQueueTransport.new(
|
16
|
+
url: 'redis://localhost:6379',
|
17
|
+
db: 7, # Use database 7 for queue management demo
|
18
|
+
queue_prefix: 'mgmt_demo',
|
19
|
+
consumer_group: 'management_workers',
|
20
|
+
block_time: 500
|
21
|
+
)
|
22
|
+
|
23
|
+
#==============================================================================
|
24
|
+
# Test Message Classes for Queue Management Demo
|
25
|
+
#==============================================================================
|
26
|
+
|
27
|
+
class TaskMessage < SmartMessage::Base
|
28
|
+
transport :redis_queue, {
|
29
|
+
url: 'redis://localhost:6379',
|
30
|
+
db: 7,
|
31
|
+
queue_prefix: 'mgmt_demo'
|
32
|
+
}
|
33
|
+
|
34
|
+
property :task_id, required: true
|
35
|
+
property :priority, default: 'normal'
|
36
|
+
property :estimated_duration, default: 30
|
37
|
+
property :worker_type, default: 'general'
|
38
|
+
|
39
|
+
def process
|
40
|
+
puts "⚙️ Processing task #{task_id} [#{priority}] - #{estimated_duration}s"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class MonitoringMessage < SmartMessage::Base
|
45
|
+
transport :redis_queue, {
|
46
|
+
url: 'redis://localhost:6379',
|
47
|
+
db: 7,
|
48
|
+
queue_prefix: 'mgmt_demo'
|
49
|
+
}
|
50
|
+
|
51
|
+
property :metric_name, required: true
|
52
|
+
property :value, required: true
|
53
|
+
property :threshold
|
54
|
+
property :alert_level, default: 'info'
|
55
|
+
|
56
|
+
def process
|
57
|
+
puts "📈 Metric: #{metric_name} = #{value} [#{alert_level}]"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class ReportMessage < SmartMessage::Base
|
62
|
+
transport :redis_queue, {
|
63
|
+
url: 'redis://localhost:6379',
|
64
|
+
db: 7,
|
65
|
+
queue_prefix: 'mgmt_demo'
|
66
|
+
}
|
67
|
+
|
68
|
+
property :report_id, required: true
|
69
|
+
property :report_type, required: true
|
70
|
+
property :data, default: {}
|
71
|
+
property :format, default: 'json'
|
72
|
+
|
73
|
+
def process
|
74
|
+
puts "📄 Generating report #{report_id} [#{report_type}] in #{format} format"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#==============================================================================
|
79
|
+
# Queue Monitoring Functions
|
80
|
+
#==============================================================================
|
81
|
+
|
82
|
+
def display_queue_statistics(transport, title = "Queue Statistics")
|
83
|
+
puts "\n📊 #{title}:"
|
84
|
+
puts "-" * (title.length + 5)
|
85
|
+
|
86
|
+
stats = transport.queue_stats
|
87
|
+
|
88
|
+
if stats.empty?
|
89
|
+
puts " No active queues found"
|
90
|
+
return
|
91
|
+
end
|
92
|
+
|
93
|
+
total_messages = 0
|
94
|
+
total_consumers = 0
|
95
|
+
|
96
|
+
stats.each do |queue_name, info|
|
97
|
+
total_messages += info[:length]
|
98
|
+
total_consumers += info[:consumers] || 0
|
99
|
+
|
100
|
+
# Extract meaningful queue name
|
101
|
+
display_name = queue_name.split('.').last.tr('_', ' ').capitalize
|
102
|
+
|
103
|
+
status_icon = case info[:length]
|
104
|
+
when 0 then '✅'
|
105
|
+
when 1..10 then '🟡'
|
106
|
+
when 11..50 then '🟠'
|
107
|
+
else '🔴'
|
108
|
+
end
|
109
|
+
|
110
|
+
puts " #{status_icon} #{display_name}:"
|
111
|
+
puts " Messages: #{info[:length]}"
|
112
|
+
puts " Pattern: #{info[:pattern] || 'N/A'}"
|
113
|
+
puts " Consumers: #{info[:consumers] || 0}"
|
114
|
+
puts ""
|
115
|
+
end
|
116
|
+
|
117
|
+
puts " 📈 Totals:"
|
118
|
+
puts " Active Queues: #{stats.size}"
|
119
|
+
puts " Total Messages: #{total_messages}"
|
120
|
+
puts " Total Consumers: #{total_consumers}"
|
121
|
+
puts ""
|
122
|
+
end
|
123
|
+
|
124
|
+
def display_routing_table(transport)
|
125
|
+
puts "\n🗺️ Routing Table:"
|
126
|
+
puts "-" * 15
|
127
|
+
|
128
|
+
routing_table = transport.routing_table
|
129
|
+
|
130
|
+
if routing_table.empty?
|
131
|
+
puts " No routing patterns configured"
|
132
|
+
return
|
133
|
+
end
|
134
|
+
|
135
|
+
routing_table.each_with_index do |(pattern, queues), index|
|
136
|
+
puts " #{index + 1}. Pattern: '#{pattern}'"
|
137
|
+
puts " Queues: #{queues.size}"
|
138
|
+
queues.each do |queue|
|
139
|
+
display_name = queue.split('.').last.tr('_', ' ').capitalize
|
140
|
+
puts " → #{display_name}"
|
141
|
+
end
|
142
|
+
puts ""
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def monitor_queue_health(transport)
|
147
|
+
stats = transport.queue_stats
|
148
|
+
health_issues = []
|
149
|
+
|
150
|
+
stats.each do |queue_name, info|
|
151
|
+
# Check for potential issues
|
152
|
+
if info[:length] > 100
|
153
|
+
health_issues << "⚠️ Queue #{queue_name} has #{info[:length]} messages (high load)"
|
154
|
+
elsif info[:length] > 0 && info[:consumers] == 0
|
155
|
+
health_issues << "🔴 Queue #{queue_name} has messages but no consumers"
|
156
|
+
elsif info[:consumers] > 10
|
157
|
+
health_issues << "⚡ Queue #{queue_name} has #{info[:consumers]} consumers (possible over-provisioning)"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
if health_issues.any?
|
162
|
+
puts "\n🏥 Queue Health Issues:"
|
163
|
+
puts "-" * 22
|
164
|
+
health_issues.each { |issue| puts " #{issue}" }
|
165
|
+
else
|
166
|
+
puts "\n✅ All queues healthy"
|
167
|
+
end
|
168
|
+
|
169
|
+
health_issues
|
170
|
+
end
|
171
|
+
|
172
|
+
def performance_metrics(transport, start_time)
|
173
|
+
current_time = Time.now
|
174
|
+
uptime = current_time - start_time
|
175
|
+
|
176
|
+
stats = transport.queue_stats
|
177
|
+
total_queues = stats.size
|
178
|
+
total_messages = stats.values.sum { |info| info[:length] }
|
179
|
+
total_consumers = stats.values.sum { |info| info[:consumers] || 0 }
|
180
|
+
|
181
|
+
puts "\n⚡ Performance Metrics:"
|
182
|
+
puts "-" * 22
|
183
|
+
puts " Uptime: #{uptime.round(2)} seconds"
|
184
|
+
puts " Active Queues: #{total_queues}"
|
185
|
+
puts " Pending Messages: #{total_messages}"
|
186
|
+
puts " Active Consumers: #{total_consumers}"
|
187
|
+
|
188
|
+
if total_consumers > 0
|
189
|
+
puts " Avg Messages/Consumer: #{(total_messages.to_f / total_consumers).round(2)}"
|
190
|
+
end
|
191
|
+
|
192
|
+
puts " Queue Density: #{total_queues > 0 ? (total_messages.to_f / total_queues).round(2) : 0} msg/queue"
|
193
|
+
end
|
194
|
+
|
195
|
+
#==============================================================================
|
196
|
+
# Queue Management Demonstration
|
197
|
+
#==============================================================================
|
198
|
+
|
199
|
+
puts "\n🚀 Starting Queue Management Demo..."
|
200
|
+
demo_start_time = Time.now
|
201
|
+
|
202
|
+
# Initial state - should be empty
|
203
|
+
display_queue_statistics(mgmt_transport, "Initial Queue State")
|
204
|
+
|
205
|
+
puts "\n1️⃣ Setting up multiple subscription patterns:"
|
206
|
+
|
207
|
+
# Pattern 1: Task processing queues
|
208
|
+
mgmt_transport.subscribe_pattern("#.*.task_processor") do |message_class, data|
|
209
|
+
parsed_data = JSON.parse(data)
|
210
|
+
puts "🔧 Task Processor: #{parsed_data['task_id']}"
|
211
|
+
end
|
212
|
+
|
213
|
+
mgmt_transport.subscribe_pattern("#.*.priority_tasks") do |message_class, data|
|
214
|
+
parsed_data = JSON.parse(data)
|
215
|
+
puts "⚡ Priority Processor: #{parsed_data['task_id']}"
|
216
|
+
end
|
217
|
+
|
218
|
+
# Pattern 2: Monitoring queues
|
219
|
+
mgmt_transport.subscribe_pattern("#.*.monitoring") do |message_class, data|
|
220
|
+
parsed_data = JSON.parse(data)
|
221
|
+
puts "📊 Monitor: #{parsed_data['metric_name']}"
|
222
|
+
end
|
223
|
+
|
224
|
+
mgmt_transport.subscribe_pattern("#.*.alerts") do |message_class, data|
|
225
|
+
parsed_data = JSON.parse(data)
|
226
|
+
puts "🚨 Alert: #{parsed_data['metric_name']} = #{parsed_data['value']}"
|
227
|
+
end
|
228
|
+
|
229
|
+
# Pattern 3: Reporting queues
|
230
|
+
mgmt_transport.subscribe_pattern("#.*.reports") do |message_class, data|
|
231
|
+
parsed_data = JSON.parse(data)
|
232
|
+
puts "📈 Report Generator: #{parsed_data['report_id']}"
|
233
|
+
end
|
234
|
+
|
235
|
+
# Pattern 4: Load balancing demo
|
236
|
+
mgmt_transport.where
|
237
|
+
.to('load_balanced_service')
|
238
|
+
.consumer_group('balanced_workers')
|
239
|
+
.subscribe do |message_class, data|
|
240
|
+
parsed_data = JSON.parse(data)
|
241
|
+
worker_id = Thread.current.object_id.to_s[-4..-1]
|
242
|
+
puts "⚖️ Balanced Worker-#{worker_id}: #{parsed_data['task_id'] || parsed_data['report_id']}"
|
243
|
+
end
|
244
|
+
|
245
|
+
sleep 1
|
246
|
+
|
247
|
+
# Show initial routing setup
|
248
|
+
display_routing_table(mgmt_transport)
|
249
|
+
display_queue_statistics(mgmt_transport, "Post-Setup Queue State")
|
250
|
+
|
251
|
+
#==============================================================================
|
252
|
+
# Message Publishing for Queue Analysis
|
253
|
+
#==============================================================================
|
254
|
+
|
255
|
+
puts "\n2️⃣ Publishing messages to populate queues:"
|
256
|
+
|
257
|
+
# Publish various task messages
|
258
|
+
puts "\n🔸 Publishing task messages..."
|
259
|
+
5.times do |i|
|
260
|
+
TaskMessage.new(
|
261
|
+
task_id: "TASK-#{sprintf('%03d', i + 1)}",
|
262
|
+
priority: ['low', 'normal', 'high', 'critical'][i % 4],
|
263
|
+
estimated_duration: rand(30..300),
|
264
|
+
worker_type: ['general', 'specialized', 'expert'][i % 3],
|
265
|
+
_sm_header: {
|
266
|
+
from: 'task_scheduler',
|
267
|
+
to: i < 3 ? 'task_processor' : 'priority_tasks'
|
268
|
+
}
|
269
|
+
).publish
|
270
|
+
end
|
271
|
+
|
272
|
+
# Publish monitoring messages
|
273
|
+
puts "\n🔸 Publishing monitoring messages..."
|
274
|
+
monitoring_metrics = [
|
275
|
+
{ name: 'cpu_usage', value: 75.5, threshold: 80, level: 'warning' },
|
276
|
+
{ name: 'memory_usage', value: 45.2, threshold: 70, level: 'info' },
|
277
|
+
{ name: 'disk_usage', value: 92.1, threshold: 90, level: 'critical' },
|
278
|
+
{ name: 'network_latency', value: 150, threshold: 100, level: 'warning' }
|
279
|
+
]
|
280
|
+
|
281
|
+
monitoring_metrics.each do |metric|
|
282
|
+
MonitoringMessage.new(
|
283
|
+
metric_name: metric[:name],
|
284
|
+
value: metric[:value],
|
285
|
+
threshold: metric[:threshold],
|
286
|
+
alert_level: metric[:level],
|
287
|
+
_sm_header: {
|
288
|
+
from: 'monitoring_system',
|
289
|
+
to: metric[:level] == 'critical' ? 'alerts' : 'monitoring'
|
290
|
+
}
|
291
|
+
).publish
|
292
|
+
end
|
293
|
+
|
294
|
+
# Publish report requests
|
295
|
+
puts "\n🔸 Publishing report requests..."
|
296
|
+
3.times do |i|
|
297
|
+
ReportMessage.new(
|
298
|
+
report_id: "RPT-#{Time.now.strftime('%Y%m%d')}-#{sprintf('%03d', i + 1)}",
|
299
|
+
report_type: ['daily_summary', 'performance_analysis', 'error_log'][i],
|
300
|
+
data: { period: '24h', format: 'detailed' },
|
301
|
+
format: ['pdf', 'json', 'csv'][i],
|
302
|
+
_sm_header: {
|
303
|
+
from: 'report_scheduler',
|
304
|
+
to: 'reports'
|
305
|
+
}
|
306
|
+
).publish
|
307
|
+
end
|
308
|
+
|
309
|
+
# Publish load balanced messages
|
310
|
+
puts "\n🔸 Publishing load balanced messages..."
|
311
|
+
8.times do |i|
|
312
|
+
message_class = [TaskMessage, ReportMessage][i % 2]
|
313
|
+
message = if message_class == TaskMessage
|
314
|
+
TaskMessage.new(
|
315
|
+
task_id: "LB-TASK-#{sprintf('%03d', i + 1)}",
|
316
|
+
priority: 'normal',
|
317
|
+
_sm_header: { from: 'load_balancer', to: 'load_balanced_service' }
|
318
|
+
)
|
319
|
+
else
|
320
|
+
ReportMessage.new(
|
321
|
+
report_id: "LB-RPT-#{sprintf('%03d', i + 1)}",
|
322
|
+
report_type: 'load_test',
|
323
|
+
_sm_header: { from: 'load_balancer', to: 'load_balanced_service' }
|
324
|
+
)
|
325
|
+
end
|
326
|
+
message.publish
|
327
|
+
end
|
328
|
+
|
329
|
+
sleep 2
|
330
|
+
|
331
|
+
# Show queue state after publishing
|
332
|
+
display_queue_statistics(mgmt_transport, "Post-Publishing Queue State")
|
333
|
+
monitor_queue_health(mgmt_transport)
|
334
|
+
performance_metrics(mgmt_transport, demo_start_time)
|
335
|
+
|
336
|
+
#==============================================================================
|
337
|
+
# Queue Monitoring Simulation
|
338
|
+
#==============================================================================
|
339
|
+
|
340
|
+
puts "\n3️⃣ Real-time queue monitoring simulation:"
|
341
|
+
|
342
|
+
puts "\n⏱️ Monitoring queue changes over time..."
|
343
|
+
5.times do |cycle|
|
344
|
+
puts "\n Monitoring Cycle #{cycle + 1}:"
|
345
|
+
|
346
|
+
# Publish some more messages to simulate ongoing activity
|
347
|
+
2.times do |i|
|
348
|
+
TaskMessage.new(
|
349
|
+
task_id: "MONITOR-#{cycle}-#{i}",
|
350
|
+
priority: 'normal',
|
351
|
+
_sm_header: { from: 'monitoring_test', to: 'task_processor' }
|
352
|
+
).publish
|
353
|
+
end
|
354
|
+
|
355
|
+
sleep 1
|
356
|
+
|
357
|
+
# Quick stats
|
358
|
+
stats = mgmt_transport.queue_stats
|
359
|
+
total_messages = stats.values.sum { |info| info[:length] }
|
360
|
+
active_queues = stats.select { |_, info| info[:length] > 0 }.size
|
361
|
+
|
362
|
+
puts " 📊 Active queues: #{active_queues}, Total messages: #{total_messages}"
|
363
|
+
|
364
|
+
# Check for health issues
|
365
|
+
health_issues = monitor_queue_health(mgmt_transport)
|
366
|
+
if health_issues.empty?
|
367
|
+
puts " ✅ System healthy"
|
368
|
+
end
|
369
|
+
|
370
|
+
sleep 1
|
371
|
+
end
|
372
|
+
|
373
|
+
#==============================================================================
|
374
|
+
# Queue Administration Operations
|
375
|
+
#==============================================================================
|
376
|
+
|
377
|
+
puts "\n4️⃣ Queue Administration Operations:"
|
378
|
+
|
379
|
+
# Show current state
|
380
|
+
puts "\n🔍 Current queue state before admin operations:"
|
381
|
+
display_queue_statistics(mgmt_transport, "Pre-Admin State")
|
382
|
+
|
383
|
+
# Admin operation 1: Clear specific queues
|
384
|
+
puts "\n🧹 Admin Operation 1: Queue Cleanup"
|
385
|
+
puts " Clearing queues with low priority messages..."
|
386
|
+
|
387
|
+
# Simulate clearing specific queues (this would be done by admin tools)
|
388
|
+
stats = mgmt_transport.queue_stats
|
389
|
+
cleared_queues = []
|
390
|
+
|
391
|
+
stats.each do |queue_name, info|
|
392
|
+
if info[:length] > 0 && queue_name.include?('task')
|
393
|
+
puts " 🗑️ Would clear queue: #{queue_name} (#{info[:length]} messages)"
|
394
|
+
cleared_queues << queue_name
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
puts " ✅ Queue cleanup simulation completed"
|
399
|
+
|
400
|
+
# Admin operation 2: Consumer group management
|
401
|
+
puts "\n👥 Admin Operation 2: Consumer Group Analysis"
|
402
|
+
routing_table = mgmt_transport.routing_table
|
403
|
+
consumer_groups = {}
|
404
|
+
|
405
|
+
routing_table.each do |pattern, queues|
|
406
|
+
# Analyze which patterns might be consumer group related
|
407
|
+
if pattern.include?('balanced') || pattern.include?('worker')
|
408
|
+
consumer_groups[pattern] = queues
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
if consumer_groups.any?
|
413
|
+
puts " Consumer group patterns found:"
|
414
|
+
consumer_groups.each do |pattern, queues|
|
415
|
+
puts " Pattern: #{pattern}"
|
416
|
+
puts " Queues: #{queues.size}"
|
417
|
+
end
|
418
|
+
else
|
419
|
+
puts " No dedicated consumer group patterns detected"
|
420
|
+
end
|
421
|
+
|
422
|
+
# Admin operation 3: Performance analysis
|
423
|
+
puts "\n📈 Admin Operation 3: Performance Analysis"
|
424
|
+
stats = mgmt_transport.queue_stats
|
425
|
+
performance_analysis = {
|
426
|
+
high_volume_queues: [],
|
427
|
+
idle_queues: [],
|
428
|
+
over_subscribed_queues: []
|
429
|
+
}
|
430
|
+
|
431
|
+
stats.each do |queue_name, info|
|
432
|
+
if info[:length] > 10
|
433
|
+
performance_analysis[:high_volume_queues] << { name: queue_name, length: info[:length] }
|
434
|
+
elsif info[:length] == 0
|
435
|
+
performance_analysis[:idle_queues] << queue_name
|
436
|
+
end
|
437
|
+
|
438
|
+
if info[:consumers] && info[:consumers] > 5
|
439
|
+
performance_analysis[:over_subscribed_queues] << { name: queue_name, consumers: info[:consumers] }
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
puts " 📊 Performance Analysis Results:"
|
444
|
+
puts " High Volume Queues: #{performance_analysis[:high_volume_queues].size}"
|
445
|
+
performance_analysis[:high_volume_queues].each do |queue|
|
446
|
+
puts " → #{queue[:name]}: #{queue[:length]} messages"
|
447
|
+
end
|
448
|
+
|
449
|
+
puts " Idle Queues: #{performance_analysis[:idle_queues].size}"
|
450
|
+
puts " Over-Subscribed Queues: #{performance_analysis[:over_subscribed_queues].size}"
|
451
|
+
|
452
|
+
#==============================================================================
|
453
|
+
# Advanced Queue Management Features
|
454
|
+
#==============================================================================
|
455
|
+
|
456
|
+
puts "\n5️⃣ Advanced Queue Management Features:"
|
457
|
+
|
458
|
+
# Feature 1: Queue pattern analysis
|
459
|
+
puts "\n🔍 Pattern Analysis:"
|
460
|
+
routing_table = mgmt_transport.routing_table
|
461
|
+
pattern_stats = {
|
462
|
+
wildcard_patterns: 0,
|
463
|
+
specific_patterns: 0,
|
464
|
+
complex_patterns: 0
|
465
|
+
}
|
466
|
+
|
467
|
+
routing_table.each do |pattern, _|
|
468
|
+
if pattern.include?('#') || pattern.include?('*')
|
469
|
+
pattern_stats[:wildcard_patterns] += 1
|
470
|
+
end
|
471
|
+
|
472
|
+
if pattern.count('.') > 2
|
473
|
+
pattern_stats[:complex_patterns] += 1
|
474
|
+
else
|
475
|
+
pattern_stats[:specific_patterns] += 1
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
puts " Pattern Statistics:"
|
480
|
+
puts " Wildcard Patterns: #{pattern_stats[:wildcard_patterns]}"
|
481
|
+
puts " Specific Patterns: #{pattern_stats[:specific_patterns]}"
|
482
|
+
puts " Complex Patterns: #{pattern_stats[:complex_patterns]}"
|
483
|
+
|
484
|
+
# Feature 2: Queue efficiency metrics
|
485
|
+
puts "\n⚡ Queue Efficiency Metrics:"
|
486
|
+
stats = mgmt_transport.queue_stats
|
487
|
+
efficiency_metrics = {
|
488
|
+
avg_messages_per_queue: 0,
|
489
|
+
queue_utilization: 0,
|
490
|
+
consumer_efficiency: 0
|
491
|
+
}
|
492
|
+
|
493
|
+
if stats.any?
|
494
|
+
total_messages = stats.values.sum { |info| info[:length] }
|
495
|
+
total_consumers = stats.values.sum { |info| info[:consumers] || 0 }
|
496
|
+
|
497
|
+
efficiency_metrics[:avg_messages_per_queue] = (total_messages.to_f / stats.size).round(2)
|
498
|
+
efficiency_metrics[:queue_utilization] = ((stats.count { |_, info| info[:length] > 0 }.to_f / stats.size) * 100).round(1)
|
499
|
+
efficiency_metrics[:consumer_efficiency] = total_consumers > 0 ? (total_messages.to_f / total_consumers).round(2) : 0
|
500
|
+
end
|
501
|
+
|
502
|
+
puts " Efficiency Metrics:"
|
503
|
+
puts " Avg Messages/Queue: #{efficiency_metrics[:avg_messages_per_queue]}"
|
504
|
+
puts " Queue Utilization: #{efficiency_metrics[:queue_utilization]}%"
|
505
|
+
puts " Messages/Consumer: #{efficiency_metrics[:consumer_efficiency]}"
|
506
|
+
|
507
|
+
# Feature 3: System recommendations
|
508
|
+
puts "\n💡 System Recommendations:"
|
509
|
+
recommendations = []
|
510
|
+
|
511
|
+
stats.each do |queue_name, info|
|
512
|
+
if info[:length] > 20
|
513
|
+
recommendations << "Consider adding more consumers to #{queue_name}"
|
514
|
+
elsif info[:length] == 0 && info[:consumers] && info[:consumers] > 2
|
515
|
+
recommendations << "Consider reducing consumers for #{queue_name}"
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
if efficiency_metrics[:queue_utilization] < 30
|
520
|
+
recommendations << "Low queue utilization - consider consolidating queues"
|
521
|
+
elsif efficiency_metrics[:queue_utilization] > 90
|
522
|
+
recommendations << "High queue utilization - consider adding more queues"
|
523
|
+
end
|
524
|
+
|
525
|
+
if recommendations.any?
|
526
|
+
recommendations.each { |rec| puts " • #{rec}" }
|
527
|
+
else
|
528
|
+
puts " ✅ System is well-optimized, no recommendations"
|
529
|
+
end
|
530
|
+
|
531
|
+
#==============================================================================
|
532
|
+
# Final System State and Summary
|
533
|
+
#==============================================================================
|
534
|
+
|
535
|
+
puts "\n6️⃣ Final System State and Summary:"
|
536
|
+
|
537
|
+
# Final statistics
|
538
|
+
display_queue_statistics(mgmt_transport, "Final Queue State")
|
539
|
+
display_routing_table(mgmt_transport)
|
540
|
+
performance_metrics(mgmt_transport, demo_start_time)
|
541
|
+
|
542
|
+
# Wait for remaining message processing
|
543
|
+
puts "\n⏳ Waiting for final message processing..."
|
544
|
+
sleep 3
|
545
|
+
|
546
|
+
# Final cleanup state
|
547
|
+
display_queue_statistics(mgmt_transport, "Post-Processing State")
|
548
|
+
|
549
|
+
# Summary statistics
|
550
|
+
final_stats = mgmt_transport.queue_stats
|
551
|
+
total_queues_created = final_stats.size
|
552
|
+
total_routing_patterns = mgmt_transport.routing_table.size
|
553
|
+
demo_duration = Time.now - demo_start_time
|
554
|
+
|
555
|
+
puts "\n📋 Demo Summary:"
|
556
|
+
puts "-" * 15
|
557
|
+
puts " Duration: #{demo_duration.round(2)} seconds"
|
558
|
+
puts " Queues Created: #{total_queues_created}"
|
559
|
+
puts " Routing Patterns: #{total_routing_patterns}"
|
560
|
+
puts " Messages Published: ~50"
|
561
|
+
puts " Admin Operations: 3"
|
562
|
+
puts " Health Checks: Multiple"
|
563
|
+
puts ""
|
564
|
+
|
565
|
+
mgmt_transport.disconnect
|
566
|
+
|
567
|
+
puts "📊 Queue Management & Monitoring demonstration completed!"
|
568
|
+
|
569
|
+
puts "\n💡 Queue Management Features Demonstrated:"
|
570
|
+
puts " ✓ Real-time queue statistics monitoring"
|
571
|
+
puts " ✓ Routing table inspection and analysis"
|
572
|
+
puts " ✓ Queue health monitoring and alerts"
|
573
|
+
puts " ✓ Performance metrics and analysis"
|
574
|
+
puts " ✓ Administrative operations and cleanup"
|
575
|
+
puts " ✓ Consumer group management"
|
576
|
+
puts " ✓ Pattern analysis and optimization"
|
577
|
+
puts " ✓ System efficiency recommendations"
|
578
|
+
|
579
|
+
puts "\n🚀 Key Management Benefits:"
|
580
|
+
puts " • Complete visibility into queue states"
|
581
|
+
puts " • Proactive health monitoring and alerting"
|
582
|
+
puts " • Performance optimization insights"
|
583
|
+
puts " • Administrative control and maintenance"
|
584
|
+
puts " • Routing pattern analysis and optimization"
|
585
|
+
puts " • Resource utilization monitoring"
|
586
|
+
puts " • Automated system recommendations"
|
587
|
+
puts " • Historical performance tracking"
|