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,697 @@
1
+ # Redis Queue Transport - Getting Started
2
+
3
+ This guide will help you get started with SmartMessage's Redis Queue Transport, the most advanced transport offering RabbitMQ-style routing with Redis performance.
4
+
5
+ ## Prerequisites
6
+
7
+ - Ruby 2.7 or higher
8
+ - Redis server running (localhost:6379 by default)
9
+ - SmartMessage gem installed
10
+
11
+ ## Installation
12
+
13
+ Add SmartMessage to your Gemfile:
14
+
15
+ ```ruby
16
+ gem 'smart_message', '~> 0.1.0'
17
+ ```
18
+
19
+ Or install directly:
20
+
21
+ ```bash
22
+ gem install smart_message
23
+ ```
24
+
25
+ Ensure Redis is running:
26
+
27
+ ```bash
28
+ # Start Redis server
29
+ redis-server
30
+
31
+ # Test Redis connection
32
+ redis-cli ping
33
+ # Should return: PONG
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ### 1. Basic Configuration
39
+
40
+ ```ruby
41
+ require 'smart_message'
42
+
43
+ # Configure SmartMessage to use Redis Queue transport
44
+ SmartMessage.configure do |config|
45
+ config.transport = :redis_queue
46
+ config.transport_options = {
47
+ url: 'redis://localhost:6379',
48
+ db: 0,
49
+ queue_prefix: 'myapp_queues',
50
+ consumer_group: 'myapp_workers'
51
+ }
52
+ end
53
+ ```
54
+
55
+ ### 2. Create Your First Message
56
+
57
+ ```ruby
58
+ class WelcomeMessage < SmartMessage::Base
59
+ transport :redis_queue
60
+
61
+ property :user_name, required: true
62
+ property :email, required: true
63
+ property :signup_date, default: -> { Time.now.strftime('%Y-%m-%d') }
64
+
65
+ def process
66
+ puts "👋 Welcome #{user_name} (#{email})! Signed up: #{signup_date}"
67
+
68
+ # Your business logic here
69
+ UserMailer.welcome_email(email, user_name).deliver_now
70
+ end
71
+ end
72
+ ```
73
+
74
+ ### 3. Subscribe to Messages
75
+
76
+ ```ruby
77
+ # Subscribe to all WelcomeMessage instances
78
+ WelcomeMessage.subscribe
79
+
80
+ puts "✅ Subscribed to welcome messages. Waiting for messages..."
81
+
82
+ # Keep the script running
83
+ sleep
84
+ ```
85
+
86
+ ### 4. Publish Messages
87
+
88
+ ```ruby
89
+ # In another script or Rails console:
90
+ WelcomeMessage.new(
91
+ user_name: 'Alice Johnson',
92
+ email: 'alice@example.com'
93
+ ).publish
94
+
95
+ puts "📤 Welcome message sent!"
96
+ ```
97
+
98
+ ## Understanding the Basics
99
+
100
+ ### What Makes Redis Queue Different?
101
+
102
+ Unlike traditional Redis pub/sub, Redis Queue Transport provides:
103
+
104
+ 1. **Persistent Queues**: Messages survive service restarts
105
+ 2. **Load Balancing**: Multiple workers share message processing
106
+ 3. **Pattern Routing**: Intelligent message routing like RabbitMQ
107
+ 4. **Queue Management**: Monitor and manage message queues
108
+
109
+ ### Routing Keys
110
+
111
+ Every message gets an enhanced routing key:
112
+
113
+ ```
114
+ namespace.message_type.from_uuid.to_uuid
115
+ ```
116
+
117
+ For example:
118
+ - `myapp.welcomemessage.signup_service.email_service`
119
+ - `myapp.ordermessage.api_gateway.payment_service`
120
+
121
+ ## Basic Patterns
122
+
123
+ ### 1. Simple Producer-Consumer
124
+
125
+ **Producer:**
126
+ ```ruby
127
+ class TaskMessage < SmartMessage::Base
128
+ transport :redis_queue
129
+
130
+ property :task_id, required: true
131
+ property :task_type, required: true
132
+ property :priority, default: 'normal'
133
+
134
+ def process
135
+ puts "⚙️ Processing task #{task_id} [#{task_type}] - Priority: #{priority}"
136
+
137
+ # Simulate work
138
+ sleep(rand(1..3))
139
+
140
+ puts "✅ Task #{task_id} completed!"
141
+ end
142
+ end
143
+
144
+ # Publish tasks
145
+ 5.times do |i|
146
+ TaskMessage.new(
147
+ task_id: "TASK-#{sprintf('%03d', i + 1)}",
148
+ task_type: ['import', 'export', 'backup', 'cleanup', 'report'][i],
149
+ priority: ['low', 'normal', 'high'][rand(3)]
150
+ ).publish
151
+ end
152
+ ```
153
+
154
+ **Consumer:**
155
+ ```ruby
156
+ # Start processing tasks
157
+ TaskMessage.subscribe
158
+
159
+ puts "🔧 Task processor started. Waiting for tasks..."
160
+ sleep # Keep running
161
+ ```
162
+
163
+ ### 2. Multiple Services Communication
164
+
165
+ **User Service:**
166
+ ```ruby
167
+ class UserCreated < SmartMessage::Base
168
+ transport :redis_queue
169
+
170
+ property :user_id, required: true
171
+ property :name, required: true
172
+ property :email, required: true
173
+
174
+ def process
175
+ puts "👤 User created: #{name} (#{email})"
176
+ end
177
+ end
178
+
179
+ # Simulate user creation
180
+ User.after_create do |user|
181
+ UserCreated.new(
182
+ user_id: user.id,
183
+ name: user.name,
184
+ email: user.email,
185
+ _sm_header: {
186
+ from: 'user_service',
187
+ to: 'notification_service'
188
+ }
189
+ ).publish
190
+ end
191
+ ```
192
+
193
+ **Notification Service:**
194
+ ```ruby
195
+ # Create transport for pattern subscription
196
+ transport = SmartMessage::Transport::RedisQueueTransport.new(
197
+ queue_prefix: 'notifications',
198
+ consumer_group: 'notification_workers'
199
+ )
200
+
201
+ # Subscribe to messages directed to notification service
202
+ transport.subscribe_pattern("#.*.notification_service") do |message_class, message_data|
203
+ data = JSON.parse(message_data)
204
+
205
+ puts "📧 Notification service received: #{message_class}"
206
+ puts " User: #{data['name']} (#{data['email']})"
207
+
208
+ # Send welcome email
209
+ WelcomeMailer.send_email(data['email'], data['name'])
210
+ end
211
+
212
+ puts "📧 Notification service started. Waiting for user events..."
213
+ sleep
214
+ ```
215
+
216
+ ### 3. Load Balancing Workers
217
+
218
+ **Setup Multiple Workers:**
219
+ ```ruby
220
+ # worker1.rb
221
+ class ProcessingTask < SmartMessage::Base
222
+ transport :redis_queue, {
223
+ consumer_group: 'processing_workers'
224
+ }
225
+
226
+ property :data, required: true
227
+
228
+ def process
229
+ worker_id = Thread.current.object_id.to_s[-4..-1]
230
+ puts "⚙️ Worker-#{worker_id} processing: #{data}"
231
+
232
+ # Simulate work
233
+ sleep(rand(0.5..2.0))
234
+
235
+ puts "✅ Worker-#{worker_id} completed: #{data}"
236
+ end
237
+ end
238
+
239
+ ProcessingTask.subscribe
240
+ puts "🔧 Worker 1 started"
241
+ sleep
242
+ ```
243
+
244
+ ```ruby
245
+ # worker2.rb (identical code, different process)
246
+ # worker3.rb (identical code, different process)
247
+ ```
248
+
249
+ **Send Work:**
250
+ ```ruby
251
+ # Send tasks that will be load balanced
252
+ 20.times do |i|
253
+ ProcessingTask.new(
254
+ data: "Task #{i + 1}",
255
+ _sm_header: {
256
+ from: 'task_scheduler',
257
+ to: 'worker_pool'
258
+ }
259
+ ).publish
260
+ end
261
+
262
+ puts "📤 Sent 20 tasks to worker pool"
263
+ ```
264
+
265
+ ## Pattern-Based Routing
266
+
267
+ ### Basic Patterns
268
+
269
+ ```ruby
270
+ transport = SmartMessage::Transport::RedisQueueTransport.new
271
+
272
+ # Messages TO specific service
273
+ transport.subscribe_pattern("#.*.payment_service") do |msg_class, data|
274
+ puts "💳 Payment service: #{msg_class}"
275
+ end
276
+
277
+ # Messages FROM specific service
278
+ transport.subscribe_pattern("#.api_gateway.*") do |msg_class, data|
279
+ puts "🌐 From API Gateway: #{msg_class}"
280
+ end
281
+
282
+ # Specific message types
283
+ transport.subscribe_pattern("order.#.*.*") do |msg_class, data|
284
+ puts "📦 Order message: #{msg_class}"
285
+ end
286
+
287
+ # Broadcast messages
288
+ transport.subscribe_pattern("#.*.broadcast") do |msg_class, data|
289
+ puts "📢 Broadcast: #{msg_class}"
290
+ end
291
+ ```
292
+
293
+ ### Wildcard Examples
294
+
295
+ | Pattern | Matches | Example |
296
+ |---------|---------|---------|
297
+ | `#.*.my_service` | All messages TO my_service | `order.ordermessage.api.my_service` |
298
+ | `#.admin.*` | All messages FROM admin | `user.usercreated.admin.notification` |
299
+ | `order.#.*.*` | All order messages | `order.ordercreated.api.payment` |
300
+ | `*.*.*.broadcast` | All broadcasts | `alert.systemalert.monitor.broadcast` |
301
+ | `#.#.#.urgent` | All urgent messages | `emergency.alert.security.urgent` |
302
+
303
+ ## Fluent API
304
+
305
+ The fluent API provides an expressive way to build subscriptions:
306
+
307
+ ```ruby
308
+ transport = SmartMessage::Transport::RedisQueueTransport.new
309
+
310
+ # Simple fluent subscriptions
311
+ transport.where
312
+ .from('api_service')
313
+ .subscribe { |msg, data| puts "From API: #{msg}" }
314
+
315
+ transport.where
316
+ .to('my_service')
317
+ .subscribe { |msg, data| puts "To Me: #{msg}" }
318
+
319
+ transport.where
320
+ .type('OrderMessage')
321
+ .subscribe { |msg, data| puts "Order: #{msg}" }
322
+
323
+ # Combined criteria
324
+ transport.where
325
+ .from('web_app')
326
+ .to('analytics_service')
327
+ .subscribe { |msg, data| puts "Web → Analytics: #{msg}" }
328
+
329
+ # Load balancing
330
+ transport.where
331
+ .to('shared_service')
332
+ .consumer_group('shared_workers')
333
+ .subscribe { |msg, data| puts "Shared worker: #{msg}" }
334
+ ```
335
+
336
+ ## Queue Management
337
+
338
+ ### Monitor Queue Status
339
+
340
+ ```ruby
341
+ transport = SmartMessage::Transport::RedisQueueTransport.new
342
+
343
+ # Get queue statistics
344
+ stats = transport.queue_stats
345
+ puts "📊 Queue Statistics:"
346
+ stats.each do |queue_name, info|
347
+ puts " #{queue_name}:"
348
+ puts " Messages: #{info[:length]}"
349
+ puts " Consumers: #{info[:consumers]}"
350
+ puts " Pattern: #{info[:pattern]}"
351
+ puts ""
352
+ end
353
+
354
+ # Show routing table
355
+ routing_table = transport.routing_table
356
+ puts "🗺️ Routing Table:"
357
+ routing_table.each do |pattern, queues|
358
+ puts " '#{pattern}' → #{queues.join(', ')}"
359
+ end
360
+ ```
361
+
362
+ ### Health Monitoring
363
+
364
+ ```ruby
365
+ def monitor_queues(transport)
366
+ stats = transport.queue_stats
367
+
368
+ # Check for problems
369
+ problems = []
370
+
371
+ stats.each do |queue, info|
372
+ if info[:length] > 100
373
+ problems << "⚠️ High load: #{queue} has #{info[:length]} messages"
374
+ elsif info[:length] > 0 && info[:consumers] == 0
375
+ problems << "🔴 No consumers: #{queue} has #{info[:length]} pending messages"
376
+ end
377
+ end
378
+
379
+ if problems.any?
380
+ puts "Queue Issues:"
381
+ problems.each { |problem| puts " #{problem}" }
382
+ else
383
+ puts "✅ All queues healthy"
384
+ end
385
+ end
386
+
387
+ # Monitor periodically
388
+ loop do
389
+ monitor_queues(transport)
390
+ sleep 30
391
+ end
392
+ ```
393
+
394
+ ## Production Configuration
395
+
396
+ ### Environment-Specific Settings
397
+
398
+ ```ruby
399
+ # config/environments/development.rb
400
+ SmartMessage.configure do |config|
401
+ config.transport = :redis_queue
402
+ config.transport_options = {
403
+ url: 'redis://localhost:6379',
404
+ db: 15, # Use test database
405
+ queue_prefix: 'myapp_dev',
406
+ consumer_group: 'dev_workers',
407
+ block_time: 1000, # 1 second for quick debugging
408
+ debug: true
409
+ }
410
+ end
411
+
412
+ # config/environments/production.rb
413
+ SmartMessage.configure do |config|
414
+ config.transport = :redis_queue
415
+ config.transport_options = {
416
+ url: ENV['REDIS_URL'] || 'redis://redis.prod.company.com:6379',
417
+ db: 0,
418
+ queue_prefix: 'myapp_prod',
419
+ consumer_group: 'prod_workers',
420
+ block_time: 5000, # 5 seconds for efficiency
421
+ max_queue_length: 50000, # Large queues
422
+ max_retries: 3,
423
+ dead_letter_queue: true,
424
+ pool_size: 10 # Connection pooling
425
+ }
426
+ end
427
+ ```
428
+
429
+ ### Worker Configuration
430
+
431
+ ```ruby
432
+ # config/workers.rb
433
+ class ApplicationWorker
434
+ def self.start
435
+ # Start multiple worker types
436
+ start_order_workers(3) # 3 order processing workers
437
+ start_email_workers(2) # 2 email workers
438
+ start_report_workers(1) # 1 report worker
439
+ start_general_workers(5) # 5 general purpose workers
440
+ end
441
+
442
+ def self.start_order_workers(count)
443
+ count.times do |i|
444
+ Thread.new do
445
+ transport = SmartMessage::Transport::RedisQueueTransport.new(
446
+ consumer_group: 'order_workers',
447
+ consumer_id: "order_worker_#{i + 1}"
448
+ )
449
+
450
+ transport.where
451
+ .to('order_service')
452
+ .consumer_group('order_workers')
453
+ .subscribe { |msg, data| puts "Order Worker #{i + 1}: #{msg}" }
454
+ end
455
+ end
456
+ end
457
+
458
+ # Similar methods for other worker types...
459
+ end
460
+
461
+ # Start all workers
462
+ ApplicationWorker.start
463
+ ```
464
+
465
+ ### Health Checks
466
+
467
+ ```ruby
468
+ # lib/health_check.rb
469
+ class RedisQueueHealthCheck
470
+ def self.check
471
+ transport = SmartMessage::Transport::RedisQueueTransport.new
472
+
473
+ begin
474
+ # Test connectivity
475
+ connected = transport.connected?
476
+
477
+ # Check queue health
478
+ stats = transport.queue_stats
479
+ queue_issues = stats.select { |_, info| info[:length] > 1000 || (info[:length] > 0 && info[:consumers] == 0) }
480
+
481
+ {
482
+ status: connected && queue_issues.empty? ? 'healthy' : 'unhealthy',
483
+ connected: connected,
484
+ total_queues: stats.size,
485
+ total_messages: stats.values.sum { |info| info[:length] },
486
+ total_consumers: stats.values.sum { |info| info[:consumers] || 0 },
487
+ queue_issues: queue_issues
488
+ }
489
+ rescue => e
490
+ {
491
+ status: 'error',
492
+ error: e.message
493
+ }
494
+ ensure
495
+ transport.disconnect
496
+ end
497
+ end
498
+ end
499
+
500
+ # Use in Rails health check endpoint
501
+ class HealthController < ApplicationController
502
+ def show
503
+ health_info = RedisQueueHealthCheck.check
504
+
505
+ if health_info[:status] == 'healthy'
506
+ render json: health_info, status: :ok
507
+ else
508
+ render json: health_info, status: :service_unavailable
509
+ end
510
+ end
511
+ end
512
+ ```
513
+
514
+ ## Common Patterns and Best Practices
515
+
516
+ ### 1. Request-Response Pattern
517
+
518
+ ```ruby
519
+ # Request message
520
+ class ProcessingRequest < SmartMessage::Base
521
+ transport :redis_queue
522
+
523
+ property :request_id, required: true
524
+ property :data, required: true
525
+ property :callback_service, required: true
526
+
527
+ def process
528
+ # Process the request
529
+ result = process_data(data)
530
+
531
+ # Send response back
532
+ ProcessingResponse.new(
533
+ request_id: request_id,
534
+ result: result,
535
+ status: 'success',
536
+ _sm_header: {
537
+ from: 'processing_service',
538
+ to: callback_service
539
+ }
540
+ ).publish
541
+ end
542
+ end
543
+
544
+ # Response message
545
+ class ProcessingResponse < SmartMessage::Base
546
+ transport :redis_queue
547
+
548
+ property :request_id, required: true
549
+ property :result, required: true
550
+ property :status, required: true
551
+
552
+ def process
553
+ puts "📥 Response for request #{request_id}: #{status}"
554
+ # Handle response
555
+ end
556
+ end
557
+ ```
558
+
559
+ ### 2. Saga Pattern
560
+
561
+ ```ruby
562
+ class OrderSaga
563
+ def self.start_order(order_data)
564
+ # Step 1: Reserve inventory
565
+ ReserveInventory.new(
566
+ saga_id: order_data[:saga_id],
567
+ order_id: order_data[:order_id],
568
+ items: order_data[:items],
569
+ _sm_header: { from: 'order_saga', to: 'inventory_service' }
570
+ ).publish
571
+ end
572
+ end
573
+
574
+ class ReserveInventory < SmartMessage::Base
575
+ transport :redis_queue
576
+
577
+ def process
578
+ if inventory_available?
579
+ # Success - continue saga
580
+ ProcessPayment.new(
581
+ saga_id: saga_id,
582
+ order_id: order_id,
583
+ amount: calculate_amount,
584
+ _sm_header: { from: 'inventory_service', to: 'payment_service' }
585
+ ).publish
586
+ else
587
+ # Failure - compensate
588
+ OrderFailed.new(
589
+ saga_id: saga_id,
590
+ reason: 'Inventory not available',
591
+ _sm_header: { from: 'inventory_service', to: 'order_saga' }
592
+ ).publish
593
+ end
594
+ end
595
+ end
596
+ ```
597
+
598
+ ### 3. Event Sourcing
599
+
600
+ ```ruby
601
+ class EventStore
602
+ def self.append_event(event)
603
+ EventAppended.new(
604
+ event_id: SecureRandom.uuid,
605
+ event_type: event.class.name,
606
+ event_data: event.to_h,
607
+ timestamp: Time.now,
608
+ _sm_header: { from: 'event_store', to: 'broadcast' }
609
+ ).publish
610
+ end
611
+ end
612
+
613
+ # Projections subscribe to events
614
+ class OrderProjection < SmartMessage::Base
615
+ transport :redis_queue
616
+
617
+ def self.subscribe_to_events
618
+ transport = SmartMessage::Transport::RedisQueueTransport.new
619
+
620
+ transport.subscribe_pattern("event.#.*.*") do |msg_class, data|
621
+ event = JSON.parse(data)
622
+
623
+ case event['event_type']
624
+ when 'OrderCreated'
625
+ update_order_projection(event['event_data'])
626
+ when 'OrderCancelled'
627
+ cancel_order_projection(event['event_data'])
628
+ end
629
+ end
630
+ end
631
+ end
632
+ ```
633
+
634
+ ## Troubleshooting
635
+
636
+ ### Debug Mode
637
+
638
+ ```ruby
639
+ # Enable detailed logging
640
+ transport = SmartMessage::Transport::RedisQueueTransport.new(
641
+ debug: true,
642
+ log_level: :debug
643
+ )
644
+
645
+ # Or set environment variable
646
+ ENV['SMART_MESSAGE_DEBUG'] = 'true'
647
+ ```
648
+
649
+ ### Common Issues
650
+
651
+ **Messages not being processed:**
652
+ ```ruby
653
+ # Check if anyone is subscribed
654
+ stats = transport.queue_stats
655
+ stats.each do |queue, info|
656
+ if info[:length] > 0 && info[:consumers] == 0
657
+ puts "No consumers for #{queue}"
658
+ end
659
+ end
660
+ ```
661
+
662
+ **Pattern not matching:**
663
+ ```ruby
664
+ # Test pattern matching
665
+ transport = SmartMessage::Transport::RedisQueueTransport.new
666
+ pattern = "#.*.my_service"
667
+ test_key = "order.ordermessage.api.my_service"
668
+
669
+ # This uses private method for testing
670
+ matches = transport.send(:routing_key_matches_pattern?, test_key, pattern)
671
+ puts "Pattern matches: #{matches}"
672
+ ```
673
+
674
+ **High memory usage:**
675
+ ```ruby
676
+ # Check for large queues
677
+ stats = transport.queue_stats
678
+ large_queues = stats.select { |_, info| info[:length] > 1000 }
679
+ puts "Large queues: #{large_queues}"
680
+
681
+ # Configure queue limits
682
+ transport = SmartMessage::Transport::RedisQueueTransport.new(
683
+ max_queue_length: 5000
684
+ )
685
+ ```
686
+
687
+ ## Next Steps
688
+
689
+ Now that you understand the basics, explore these advanced topics:
690
+
691
+ 1. **[Advanced Routing Patterns](redis-queue-patterns.md)** - Complex routing scenarios
692
+ 2. **[Production Deployment](redis-queue-production.md)** - Production-ready configurations
693
+ 3. **[Complete Transport Reference](../transports/redis-queue-transport.md)** - Full API documentation
694
+
695
+ Or dive into the [complete examples](https://github.com/madbomber/smart_message/tree/main/examples/redis_queue) to see real-world usage patterns.
696
+
697
+ The Redis Queue Transport provides the perfect balance of performance, reliability, and intelligent routing for modern Ruby applications. Start with these patterns and gradually incorporate more advanced features as your needs grow.