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.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/deploy-github-pages.yml +38 -0
  3. data/.gitignore +5 -0
  4. data/CHANGELOG.md +30 -0
  5. data/Gemfile.lock +35 -4
  6. data/README.md +169 -71
  7. data/Rakefile +29 -4
  8. data/docs/assets/images/ddq_architecture.svg +130 -0
  9. data/docs/assets/images/dlq_architecture.svg +115 -0
  10. data/docs/assets/images/enhanced-dual-publishing.svg +136 -0
  11. data/docs/assets/images/enhanced-fluent-api.svg +149 -0
  12. data/docs/assets/images/enhanced-microservices-routing.svg +115 -0
  13. data/docs/assets/images/enhanced-pattern-matching.svg +107 -0
  14. data/docs/assets/images/fluent-api-demo.svg +59 -0
  15. data/docs/assets/images/performance-comparison.svg +161 -0
  16. data/docs/assets/images/redis-basic-architecture.svg +53 -0
  17. data/docs/assets/images/redis-enhanced-architecture.svg +88 -0
  18. data/docs/assets/images/redis-queue-architecture.svg +101 -0
  19. data/docs/assets/images/smart_message.jpg +0 -0
  20. data/docs/assets/images/smart_message_walking.jpg +0 -0
  21. data/docs/assets/images/smartmessage_architecture_overview.svg +173 -0
  22. data/docs/assets/images/transport-comparison-matrix.svg +171 -0
  23. data/docs/assets/javascripts/mathjax.js +17 -0
  24. data/docs/assets/stylesheets/extra.css +51 -0
  25. data/docs/{addressing.md → core-concepts/addressing.md} +5 -7
  26. data/docs/{architecture.md → core-concepts/architecture.md} +78 -138
  27. data/docs/{dispatcher.md → core-concepts/dispatcher.md} +21 -21
  28. data/docs/{message_filtering.md → core-concepts/message-filtering.md} +2 -3
  29. data/docs/{message_processing.md → core-concepts/message-processing.md} +17 -17
  30. data/docs/{troubleshooting.md → development/troubleshooting.md} +7 -7
  31. data/docs/{examples.md → getting-started/examples.md} +115 -89
  32. data/docs/{getting-started.md → getting-started/quick-start.md} +47 -18
  33. data/docs/guides/redis-queue-getting-started.md +697 -0
  34. data/docs/guides/redis-queue-patterns.md +889 -0
  35. data/docs/guides/redis-queue-production.md +1091 -0
  36. data/docs/index.md +64 -0
  37. data/docs/{dead_letter_queue.md → reference/dead-letter-queue.md} +2 -3
  38. data/docs/{logging.md → reference/logging.md} +1 -1
  39. data/docs/{message_deduplication.md → reference/message-deduplication.md} +1 -0
  40. data/docs/{proc_handlers_summary.md → reference/proc-handlers.md} +7 -6
  41. data/docs/{serializers.md → reference/serializers.md} +3 -5
  42. data/docs/{transports.md → reference/transports.md} +133 -11
  43. data/docs/transports/memory-transport.md +374 -0
  44. data/docs/transports/redis-enhanced-transport.md +524 -0
  45. data/docs/transports/redis-queue-transport.md +1304 -0
  46. data/docs/transports/redis-transport-comparison.md +496 -0
  47. data/docs/transports/redis-transport.md +509 -0
  48. data/examples/README.md +98 -5
  49. data/examples/city_scenario/911_emergency_call_flow.svg +99 -0
  50. data/examples/city_scenario/README.md +515 -0
  51. data/examples/city_scenario/ai_visitor_intelligence_flow.svg +108 -0
  52. data/examples/city_scenario/citizen.rb +195 -0
  53. data/examples/city_scenario/city_diagram.svg +125 -0
  54. data/examples/city_scenario/common/health_monitor.rb +80 -0
  55. data/examples/city_scenario/common/logger.rb +30 -0
  56. data/examples/city_scenario/emergency_dispatch_center.rb +270 -0
  57. data/examples/city_scenario/fire_department.rb +446 -0
  58. data/examples/city_scenario/fire_emergency_flow.svg +95 -0
  59. data/examples/city_scenario/health_department.rb +100 -0
  60. data/examples/city_scenario/health_monitoring_system.svg +130 -0
  61. data/examples/city_scenario/house.rb +244 -0
  62. data/examples/city_scenario/local_bank.rb +217 -0
  63. data/examples/city_scenario/messages/emergency_911_message.rb +81 -0
  64. data/examples/city_scenario/messages/emergency_resolved_message.rb +43 -0
  65. data/examples/city_scenario/messages/fire_dispatch_message.rb +43 -0
  66. data/examples/city_scenario/messages/fire_emergency_message.rb +45 -0
  67. data/examples/city_scenario/messages/health_check_message.rb +22 -0
  68. data/examples/city_scenario/messages/health_status_message.rb +35 -0
  69. data/examples/city_scenario/messages/police_dispatch_message.rb +46 -0
  70. data/examples/city_scenario/messages/silent_alarm_message.rb +38 -0
  71. data/examples/city_scenario/police_department.rb +316 -0
  72. data/examples/city_scenario/redis_monitor.rb +129 -0
  73. data/examples/city_scenario/redis_stats.rb +743 -0
  74. data/examples/city_scenario/room_for_improvement.md +240 -0
  75. data/examples/city_scenario/security_emergency_flow.svg +95 -0
  76. data/examples/city_scenario/service_internal_architecture.svg +154 -0
  77. data/examples/city_scenario/smart_message_ai_agent.rb +364 -0
  78. data/examples/city_scenario/start_demo.sh +236 -0
  79. data/examples/city_scenario/stop_demo.sh +106 -0
  80. data/examples/city_scenario/visitor.rb +631 -0
  81. data/examples/{10_message_deduplication.rb → memory/01_message_deduplication_demo.rb} +1 -1
  82. data/examples/{09_dead_letter_queue_demo.rb → memory/02_dead_letter_queue_demo.rb} +13 -40
  83. data/examples/{01_point_to_point_orders.rb → memory/03_point_to_point_orders.rb} +1 -1
  84. data/examples/{02_publish_subscribe_events.rb → memory/04_publish_subscribe_events.rb} +2 -2
  85. data/examples/{03_many_to_many_chat.rb → memory/05_many_to_many_chat.rb} +4 -4
  86. data/examples/{show_me.rb → memory/06_pretty_print_demo.rb} +1 -1
  87. data/examples/{05_proc_handlers.rb → memory/07_proc_handlers_demo.rb} +2 -2
  88. data/examples/{06_custom_logger_example.rb → memory/08_custom_logger_demo.rb} +17 -14
  89. data/examples/{07_error_handling_scenarios.rb → memory/09_error_handling_demo.rb} +4 -4
  90. data/examples/{08_entity_addressing_basic.rb → memory/10_entity_addressing_basic.rb} +8 -8
  91. data/examples/{08_entity_addressing_with_filtering.rb → memory/11_entity_addressing_with_filtering.rb} +6 -6
  92. data/examples/{09_regex_filtering_microservices.rb → memory/12_regex_filtering_microservices.rb} +2 -2
  93. data/examples/{10_header_block_configuration.rb → memory/13_header_block_configuration.rb} +6 -6
  94. data/examples/{11_global_configuration_example.rb → memory/14_global_configuration_demo.rb} +19 -8
  95. data/examples/{show_logger.rb → memory/15_logger_demo.rb} +1 -1
  96. data/examples/memory/README.md +163 -0
  97. data/examples/memory/memory_transport_architecture.svg +90 -0
  98. data/examples/memory/point_to_point_pattern.svg +94 -0
  99. data/examples/memory/publish_subscribe_pattern.svg +125 -0
  100. data/examples/{04_redis_smart_home_iot.rb → redis/01_smart_home_iot_demo.rb} +5 -5
  101. data/examples/redis/README.md +230 -0
  102. data/examples/redis/alert_system_flow.svg +127 -0
  103. data/examples/redis/dashboard_status_flow.svg +107 -0
  104. data/examples/redis/device_command_flow.svg +113 -0
  105. data/examples/redis/redis_transport_architecture.svg +115 -0
  106. data/examples/{smart_home_iot_dataflow.md → redis/smart_home_iot_dataflow.md} +4 -116
  107. data/examples/redis/smart_home_system_architecture.svg +133 -0
  108. data/examples/redis_enhanced/README.md +319 -0
  109. data/examples/redis_enhanced/enhanced_01_basic_patterns.rb +233 -0
  110. data/examples/redis_enhanced/enhanced_02_fluent_api.rb +331 -0
  111. data/examples/redis_enhanced/enhanced_03_dual_publishing.rb +281 -0
  112. data/examples/redis_enhanced/enhanced_04_advanced_routing.rb +419 -0
  113. data/examples/redis_queue/01_basic_messaging.rb +221 -0
  114. data/examples/redis_queue/01_comprehensive_examples.rb +508 -0
  115. data/examples/redis_queue/02_pattern_routing.rb +405 -0
  116. data/examples/redis_queue/03_fluent_api.rb +422 -0
  117. data/examples/redis_queue/04_load_balancing.rb +486 -0
  118. data/examples/redis_queue/05_microservices.rb +735 -0
  119. data/examples/redis_queue/06_emergency_alerts.rb +777 -0
  120. data/examples/redis_queue/07_queue_management.rb +587 -0
  121. data/examples/redis_queue/README.md +366 -0
  122. data/examples/redis_queue/enhanced_01_basic_patterns.rb +233 -0
  123. data/examples/redis_queue/enhanced_02_fluent_api.rb +331 -0
  124. data/examples/redis_queue/enhanced_03_dual_publishing.rb +281 -0
  125. data/examples/redis_queue/enhanced_04_advanced_routing.rb +419 -0
  126. data/examples/redis_queue/redis_queue_architecture.svg +148 -0
  127. data/ideas/README.md +41 -0
  128. data/ideas/agents.md +1001 -0
  129. data/ideas/database_transport.md +980 -0
  130. data/ideas/improvement.md +359 -0
  131. data/ideas/meshage.md +1788 -0
  132. data/ideas/message_discovery.md +178 -0
  133. data/ideas/message_schema.md +1381 -0
  134. data/lib/smart_message/.idea/.gitignore +8 -0
  135. data/lib/smart_message/.idea/markdown.xml +6 -0
  136. data/lib/smart_message/.idea/misc.xml +4 -0
  137. data/lib/smart_message/.idea/modules.xml +8 -0
  138. data/lib/smart_message/.idea/smart_message.iml +16 -0
  139. data/lib/smart_message/.idea/vcs.xml +6 -0
  140. data/lib/smart_message/addressing.rb +15 -0
  141. data/lib/smart_message/base.rb +0 -2
  142. data/lib/smart_message/configuration.rb +1 -1
  143. data/lib/smart_message/logger.rb +15 -4
  144. data/lib/smart_message/plugins.rb +5 -2
  145. data/lib/smart_message/serializer.rb +14 -0
  146. data/lib/smart_message/transport/redis_enhanced_transport.rb +399 -0
  147. data/lib/smart_message/transport/redis_queue_transport.rb +555 -0
  148. data/lib/smart_message/transport/registry.rb +1 -0
  149. data/lib/smart_message/transport.rb +34 -1
  150. data/lib/smart_message/version.rb +1 -1
  151. data/lib/smart_message.rb +5 -52
  152. data/mkdocs.yml +184 -0
  153. data/p2p_plan.md +326 -0
  154. data/p2p_roadmap.md +287 -0
  155. data/smart_message.gemspec +2 -0
  156. data/smart_message.svg +51 -0
  157. metadata +170 -44
  158. data/docs/README.md +0 -57
  159. data/examples/dead_letters.jsonl +0 -12
  160. data/examples/temp.txt +0 -94
  161. data/examples/tmux_chat/README.md +0 -283
  162. data/examples/tmux_chat/bot_agent.rb +0 -278
  163. data/examples/tmux_chat/human_agent.rb +0 -199
  164. data/examples/tmux_chat/room_monitor.rb +0 -160
  165. data/examples/tmux_chat/shared_chat_system.rb +0 -328
  166. data/examples/tmux_chat/start_chat_demo.sh +0 -190
  167. data/examples/tmux_chat/stop_chat_demo.sh +0 -22
  168. /data/docs/{properties.md → core-concepts/properties.md} +0 -0
  169. /data/docs/{ideas_to_think_about.md → development/ideas.md} +0 -0
@@ -0,0 +1,486 @@
1
+ #!/usr/bin/env ruby
2
+ # examples/redis_queue/04_load_balancing.rb
3
+ # Load balancing and consumer groups with Redis Queue Transport
4
+
5
+ require_relative '../../lib/smart_message'
6
+
7
+ puts "⚖️ Redis Queue Transport - Load Balancing Demo"
8
+ puts "=" * 50
9
+
10
+ #==============================================================================
11
+ # Transport Configuration
12
+ #==============================================================================
13
+
14
+ # Create shared transport for load balancing examples
15
+ shared_transport = SmartMessage::Transport::RedisQueueTransport.new(
16
+ url: 'redis://localhost:6379',
17
+ db: 4, # Use database 4 for load balancing examples
18
+ queue_prefix: 'load_balance_demo',
19
+ consumer_group: 'demo_workers',
20
+ block_time: 500 # Fast response for demo
21
+ )
22
+
23
+ #==============================================================================
24
+ # Work Message Classes
25
+ #==============================================================================
26
+
27
+ class ProcessingTask < SmartMessage::Base
28
+ transport :redis_queue, {
29
+ url: 'redis://localhost:6379',
30
+ db: 4,
31
+ queue_prefix: 'load_balance_demo'
32
+ }
33
+
34
+ property :task_id, required: true
35
+ property :task_type, required: true
36
+ property :complexity, default: 'medium' # low, medium, high
37
+ property :estimated_seconds, default: 1
38
+ property :payload, default: {}
39
+
40
+ def process
41
+ complexity_icon = case complexity
42
+ when 'high' then '🔥'
43
+ when 'medium' then '⚡'
44
+ when 'low' then '🍃'
45
+ else '⚙️'
46
+ end
47
+
48
+ puts "#{complexity_icon} Processing #{task_id} [#{task_type}] - #{complexity} complexity (#{estimated_seconds}s)"
49
+
50
+ # Simulate work
51
+ sleep(estimated_seconds * 0.1) # Scale down for demo
52
+
53
+ puts "✅ Completed #{task_id} by worker #{Thread.current.object_id.to_s[-4..-1]}"
54
+ end
55
+ end
56
+
57
+ class EmailTask < SmartMessage::Base
58
+ transport :redis_queue, {
59
+ url: 'redis://localhost:6379',
60
+ db: 4,
61
+ queue_prefix: 'load_balance_demo'
62
+ }
63
+
64
+ property :email_id, required: true
65
+ property :recipient, required: true
66
+ property :subject, required: true
67
+ property :template, default: 'default'
68
+ property :priority, default: 'normal'
69
+
70
+ def process
71
+ priority_icon = case priority
72
+ when 'urgent' then '🚨'
73
+ when 'high' then '❗'
74
+ when 'normal' then '📧'
75
+ when 'low' then '📮'
76
+ else '📬'
77
+ end
78
+
79
+ worker_id = Thread.current.object_id.to_s[-4..-1]
80
+ puts "#{priority_icon} Worker-#{worker_id}: Email #{email_id} → #{recipient}"
81
+ puts " Subject: #{subject} [#{priority}]"
82
+
83
+ # Simulate email sending
84
+ sleep(rand(0.5..1.5))
85
+
86
+ puts "📤 Email #{email_id} sent by worker-#{worker_id}"
87
+ end
88
+ end
89
+
90
+ class DataAnalysisTask < SmartMessage::Base
91
+ transport :redis_queue, {
92
+ url: 'redis://localhost:6379',
93
+ db: 4,
94
+ queue_prefix: 'load_balance_demo'
95
+ }
96
+
97
+ property :analysis_id, required: true
98
+ property :dataset, required: true
99
+ property :analysis_type, required: true
100
+ property :rows, default: 1000
101
+ property :columns, default: 10
102
+
103
+ def process
104
+ worker_id = Thread.current.object_id.to_s[-4..-1]
105
+ puts "📊 Worker-#{worker_id}: Analyzing #{dataset} [#{analysis_type}]"
106
+ puts " Dataset: #{rows} rows × #{columns} columns"
107
+
108
+ # Simulate analysis work
109
+ sleep(rand(0.8..2.0))
110
+
111
+ puts "🎯 Analysis #{analysis_id} completed by worker-#{worker_id}"
112
+ end
113
+ end
114
+
115
+ #==============================================================================
116
+ # Consumer Group Setup
117
+ #==============================================================================
118
+
119
+ puts "\n👥 Setting up consumer groups for load balancing:"
120
+
121
+ # Group 1: General processing workers
122
+ puts "1️⃣ Setting up 'processing_workers' group (3 workers)"
123
+ processing_workers = []
124
+ 3.times do |i|
125
+ worker_thread = Thread.new do
126
+ worker_transport = SmartMessage::Transport::RedisQueueTransport.new(
127
+ url: 'redis://localhost:6379',
128
+ db: 4,
129
+ queue_prefix: 'load_balance_demo',
130
+ consumer_group: 'processing_workers',
131
+ block_time: 1000
132
+ )
133
+
134
+ # Subscribe to processing tasks directed to worker pool
135
+ worker_transport.where
136
+ .to('worker_pool')
137
+ .consumer_group('processing_workers')
138
+ .subscribe do |message_class, message_data|
139
+ data = JSON.parse(message_data)
140
+ worker_id = Thread.current.object_id.to_s[-4..-1]
141
+ puts "⚙️ Worker-#{i+1}-#{worker_id} received: #{data['task_id'] || data['email_id'] || data['analysis_id']}"
142
+ end
143
+ end
144
+ processing_workers << worker_thread
145
+ end
146
+
147
+ # Group 2: Email workers
148
+ puts "2️⃣ Setting up 'email_workers' group (2 workers)"
149
+ email_workers = []
150
+ 2.times do |i|
151
+ worker_thread = Thread.new do
152
+ worker_transport = SmartMessage::Transport::RedisQueueTransport.new(
153
+ url: 'redis://localhost:6379',
154
+ db: 4,
155
+ queue_prefix: 'load_balance_demo',
156
+ consumer_group: 'email_workers',
157
+ block_time: 1000
158
+ )
159
+
160
+ # Subscribe to email tasks
161
+ worker_transport.where
162
+ .type('EmailTask')
163
+ .consumer_group('email_workers')
164
+ .subscribe do |message_class, message_data|
165
+ data = JSON.parse(message_data)
166
+ worker_id = Thread.current.object_id.to_s[-4..-1]
167
+ puts "📧 EmailWorker-#{i+1}-#{worker_id} received: #{data['email_id']}"
168
+ end
169
+ end
170
+ email_workers << worker_thread
171
+ end
172
+
173
+ # Group 3: Analytics workers
174
+ puts "3️⃣ Setting up 'analytics_workers' group (4 workers)"
175
+ analytics_workers = []
176
+ 4.times do |i|
177
+ worker_thread = Thread.new do
178
+ worker_transport = SmartMessage::Transport::RedisQueueTransport.new(
179
+ url: 'redis://localhost:6379',
180
+ db: 4,
181
+ queue_prefix: 'load_balance_demo',
182
+ consumer_group: 'analytics_workers',
183
+ block_time: 1000
184
+ )
185
+
186
+ # Subscribe to analytics tasks
187
+ worker_transport.where
188
+ .type('DataAnalysisTask')
189
+ .consumer_group('analytics_workers')
190
+ .subscribe do |message_class, message_data|
191
+ data = JSON.parse(message_data)
192
+ worker_id = Thread.current.object_id.to_s[-4..-1]
193
+ puts "📊 AnalyticsWorker-#{i+1}-#{worker_id} received: #{data['analysis_id']}"
194
+ end
195
+ end
196
+ analytics_workers << worker_thread
197
+ end
198
+
199
+ # Give workers time to start
200
+ sleep 2
201
+
202
+ #==============================================================================
203
+ # Load Balancing Demonstration
204
+ #==============================================================================
205
+
206
+ puts "\n📤 Demonstrating load balancing with multiple workers:"
207
+
208
+ # Test 1: Processing tasks distributed among 3 workers
209
+ puts "\n🔸 Test 1: General processing tasks (distributed among 3 workers)"
210
+ 5.times do |i|
211
+ ProcessingTask.new(
212
+ task_id: "PROC-#{sprintf('%03d', i + 1)}",
213
+ task_type: ['data_import', 'file_conversion', 'image_resize', 'pdf_generation', 'backup'][i],
214
+ complexity: ['low', 'medium', 'high', 'medium', 'low'][i],
215
+ estimated_seconds: [1, 2, 3, 2, 1][i],
216
+ payload: { batch_size: rand(100..1000) },
217
+ _sm_header: {
218
+ from: 'task_scheduler',
219
+ to: 'worker_pool'
220
+ }
221
+ ).publish
222
+ end
223
+
224
+ sleep 3
225
+
226
+ # Test 2: Email tasks distributed among 2 workers
227
+ puts "\n🔸 Test 2: Email tasks (distributed among 2 workers)"
228
+ 6.times do |i|
229
+ EmailTask.new(
230
+ email_id: "EMAIL-#{sprintf('%03d', i + 1)}",
231
+ recipient: "user#{i + 1}@example.com",
232
+ subject: [
233
+ 'Welcome to our service!',
234
+ 'Your order confirmation',
235
+ 'Password reset request',
236
+ 'Monthly newsletter',
237
+ 'Account verification required',
238
+ 'Special offer inside!'
239
+ ][i],
240
+ template: ['welcome', 'order', 'password_reset', 'newsletter', 'verification', 'promotion'][i],
241
+ priority: ['normal', 'high', 'urgent', 'low', 'normal', 'high'][i],
242
+ _sm_header: {
243
+ from: 'email_service',
244
+ to: 'email_queue'
245
+ }
246
+ ).publish
247
+ end
248
+
249
+ sleep 4
250
+
251
+ # Test 3: Analytics tasks distributed among 4 workers
252
+ puts "\n🔸 Test 3: Analytics tasks (distributed among 4 workers)"
253
+ 8.times do |i|
254
+ DataAnalysisTask.new(
255
+ analysis_id: "ANALYSIS-#{sprintf('%03d', i + 1)}",
256
+ dataset: "dataset_#{i + 1}",
257
+ analysis_type: ['regression', 'classification', 'clustering', 'time_series', 'correlation', 'anomaly_detection', 'forecasting', 'segmentation'][i],
258
+ rows: rand(1000..10000),
259
+ columns: rand(5..50),
260
+ _sm_header: {
261
+ from: 'analytics_service',
262
+ to: 'analytics_queue'
263
+ }
264
+ ).publish
265
+ end
266
+
267
+ sleep 5
268
+
269
+ #==============================================================================
270
+ # High-Volume Load Test
271
+ #==============================================================================
272
+
273
+ puts "\n🚀 High-volume load balancing test:"
274
+
275
+ # Publish many tasks rapidly to see load distribution
276
+ puts "Publishing 20 processing tasks rapidly..."
277
+ start_time = Time.now
278
+
279
+ 20.times do |i|
280
+ ProcessingTask.new(
281
+ task_id: "LOAD-#{sprintf('%03d', i + 1)}",
282
+ task_type: 'load_test',
283
+ complexity: ['low', 'medium', 'high'].sample,
284
+ estimated_seconds: rand(1..3),
285
+ _sm_header: {
286
+ from: 'load_tester',
287
+ to: 'worker_pool'
288
+ }
289
+ ).publish
290
+ end
291
+
292
+ end_time = Time.now
293
+ puts "✅ Published 20 tasks in #{(end_time - start_time).round(3)} seconds"
294
+
295
+ # Wait for processing
296
+ puts "\n⏳ Waiting for load test completion..."
297
+ sleep 8
298
+
299
+ #==============================================================================
300
+ # Priority-Based Load Balancing
301
+ #==============================================================================
302
+
303
+ puts "\n⭐ Priority-based load balancing:"
304
+
305
+ # Set up priority workers
306
+ puts "Setting up high-priority worker group..."
307
+ priority_transport = SmartMessage::Transport::RedisQueueTransport.new(
308
+ url: 'redis://localhost:6379',
309
+ db: 4,
310
+ queue_prefix: 'load_balance_demo',
311
+ consumer_group: 'priority_workers',
312
+ block_time: 500
313
+ )
314
+
315
+ # Priority worker subscription
316
+ priority_worker = Thread.new do
317
+ priority_transport.where
318
+ .to('priority_queue')
319
+ .consumer_group('priority_workers')
320
+ .subscribe do |message_class, message_data|
321
+ data = JSON.parse(message_data)
322
+ puts "🌟 PRIORITY Worker handling: #{data['task_id'] || data['email_id']}"
323
+ end
324
+ end
325
+
326
+ sleep 1
327
+
328
+ # Publish priority tasks
329
+ puts "Publishing high-priority tasks..."
330
+ 3.times do |i|
331
+ ProcessingTask.new(
332
+ task_id: "PRIORITY-#{sprintf('%03d', i + 1)}",
333
+ task_type: 'critical_task',
334
+ complexity: 'high',
335
+ estimated_seconds: 1,
336
+ _sm_header: {
337
+ from: 'urgent_scheduler',
338
+ to: 'priority_queue'
339
+ }
340
+ ).publish
341
+ end
342
+
343
+ # Publish priority emails
344
+ 2.times do |i|
345
+ EmailTask.new(
346
+ email_id: "URGENT-EMAIL-#{sprintf('%03d', i + 1)}",
347
+ recipient: "admin#{i + 1}@company.com",
348
+ subject: 'URGENT: System Alert',
349
+ priority: 'urgent',
350
+ _sm_header: {
351
+ from: 'alert_system',
352
+ to: 'priority_queue'
353
+ }
354
+ ).publish
355
+ end
356
+
357
+ sleep 3
358
+
359
+ #==============================================================================
360
+ # Load Balancing Statistics
361
+ #==============================================================================
362
+
363
+ puts "\n📊 Load Balancing Statistics:"
364
+
365
+ # Show queue statistics
366
+ stats = shared_transport.queue_stats
367
+ puts "\nQueue lengths after load balancing:"
368
+ total_queued = 0
369
+ stats.each do |queue_name, info|
370
+ total_queued += info[:length]
371
+ puts " #{queue_name}: #{info[:length]} messages (#{info[:consumers]} consumers)"
372
+ end
373
+
374
+ puts "\nTotal messages remaining in queues: #{total_queued}"
375
+
376
+ # Show routing table for consumer groups
377
+ routing_table = shared_transport.routing_table
378
+ puts "\nActive consumer group patterns:"
379
+ routing_table.each do |pattern, queues|
380
+ puts " Pattern: '#{pattern}'"
381
+ puts " Queues: #{queues.join(', ')}"
382
+ end
383
+
384
+ #==============================================================================
385
+ # Worker Performance Comparison
386
+ #==============================================================================
387
+
388
+ puts "\n⚡ Worker Performance Demonstration:"
389
+
390
+ # Create workers with different processing speeds
391
+ puts "Creating workers with different performance characteristics..."
392
+
393
+ # Fast worker
394
+ fast_worker_transport = SmartMessage::Transport::RedisQueueTransport.new(
395
+ url: 'redis://localhost:6379',
396
+ db: 4,
397
+ queue_prefix: 'load_balance_demo',
398
+ consumer_group: 'performance_test_workers'
399
+ )
400
+
401
+ fast_worker = Thread.new do
402
+ fast_worker_transport.where
403
+ .to('performance_test')
404
+ .consumer_group('performance_test_workers')
405
+ .subscribe do |message_class, message_data|
406
+ data = JSON.parse(message_data)
407
+ puts "🚀 FAST Worker: #{data['task_id']} (processed quickly)"
408
+ sleep(0.1) # Fast processing
409
+ end
410
+ end
411
+
412
+ # Slow worker
413
+ slow_worker_transport = SmartMessage::Transport::RedisQueueTransport.new(
414
+ url: 'redis://localhost:6379',
415
+ db: 4,
416
+ queue_prefix: 'load_balance_demo',
417
+ consumer_group: 'performance_test_workers'
418
+ )
419
+
420
+ slow_worker = Thread.new do
421
+ slow_worker_transport.where
422
+ .to('performance_test')
423
+ .consumer_group('performance_test_workers')
424
+ .subscribe do |message_class, message_data|
425
+ data = JSON.parse(message_data)
426
+ puts "🐌 SLOW Worker: #{data['task_id']} (processing slowly...)"
427
+ sleep(2.0) # Slow processing
428
+ end
429
+ end
430
+
431
+ sleep 1
432
+
433
+ # Send tasks to both workers
434
+ puts "Sending 10 tasks to mixed-speed worker group..."
435
+ 10.times do |i|
436
+ ProcessingTask.new(
437
+ task_id: "PERF-#{sprintf('%03d', i + 1)}",
438
+ task_type: 'performance_test',
439
+ complexity: 'medium',
440
+ _sm_header: {
441
+ from: 'performance_tester',
442
+ to: 'performance_test'
443
+ }
444
+ ).publish
445
+ end
446
+
447
+ puts "⏳ Observing how Redis Queue balances load between fast and slow workers..."
448
+ sleep 8
449
+
450
+ #==============================================================================
451
+ # Cleanup
452
+ #==============================================================================
453
+
454
+ puts "\n🧹 Cleaning up workers and connections..."
455
+
456
+ # Stop all worker threads
457
+ [processing_workers, email_workers, analytics_workers, priority_worker, fast_worker, slow_worker].flatten.each do |thread|
458
+ thread.kill if thread.alive?
459
+ end
460
+
461
+ # Disconnect transports
462
+ shared_transport.disconnect
463
+ priority_transport.disconnect
464
+ fast_worker_transport.disconnect
465
+ slow_worker_transport.disconnect
466
+
467
+ puts "\n⚖️ Load balancing demonstration completed!"
468
+
469
+ puts "\n💡 Load Balancing Features Demonstrated:"
470
+ puts " ✓ Consumer groups for work distribution"
471
+ puts " ✓ Multiple workers sharing same queue"
472
+ puts " ✓ Round-robin task distribution"
473
+ puts " ✓ Different worker group configurations"
474
+ puts " ✓ High-volume load testing"
475
+ puts " ✓ Priority-based routing"
476
+ puts " ✓ Mixed-performance worker handling"
477
+ puts " ✓ Real-time queue monitoring"
478
+
479
+ puts "\n🚀 Key Benefits:"
480
+ puts " • Automatic load distribution via Redis BRPOP"
481
+ puts " • Scalable worker pool management"
482
+ puts " • Fair work distribution among workers"
483
+ puts " • Consumer group isolation"
484
+ puts " • High-throughput task processing"
485
+ puts " • Fault-tolerant worker coordination"
486
+ puts " • Zero-configuration load balancing"