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,331 @@
1
+ #!/usr/bin/env ruby
2
+ # examples/redis_queue/enhanced_02_fluent_api.rb
3
+ # Redis Enhanced Transport - Fluent API Demonstration
4
+
5
+ require_relative '../../lib/smart_message'
6
+ require 'smart_message/transport/redis_enhanced_transport'
7
+
8
+ puts "🚀 Redis Enhanced Transport - Fluent API Demo"
9
+ puts "=" * 50
10
+
11
+ # Create enhanced Redis transport instance
12
+ transport = SmartMessage::Transport::RedisEnhancedTransport.new(
13
+ url: 'redis://localhost:6379',
14
+ db: 3, # Use database 3 for fluent API examples
15
+ auto_subscribe: true
16
+ )
17
+
18
+ #==============================================================================
19
+ # Define Message Classes for Microservices Architecture
20
+ #==============================================================================
21
+
22
+ class UserRegistrationMessage < SmartMessage::Base
23
+ from 'web-app'
24
+ to 'user-service'
25
+
26
+ transport transport
27
+ serializer SmartMessage::Serializer::Json.new
28
+
29
+ property :user_id, required: true
30
+ property :email, required: true
31
+ property :name, required: true
32
+
33
+ def self.process(wrapper)
34
+ header, payload = wrapper.split
35
+ data = JSON.parse(payload)
36
+
37
+ puts "👤 [USER SERVICE] New user registration: #{data['name']} (#{data['email']})"
38
+ puts " User ID: #{data['user_id']}"
39
+ puts
40
+ end
41
+ end
42
+
43
+ class EmailNotificationMessage < SmartMessage::Base
44
+ from 'user-service'
45
+ to 'notification-service'
46
+
47
+ transport transport
48
+ serializer SmartMessage::Serializer::Json.new
49
+
50
+ property :recipient, required: true
51
+ property :subject, required: true
52
+ property :body, required: true
53
+ property :template, default: 'default'
54
+
55
+ def self.process(wrapper)
56
+ header, payload = wrapper.split
57
+ data = JSON.parse(payload)
58
+
59
+ puts "📧 [NOTIFICATION SERVICE] Sending email to #{data['recipient']}"
60
+ puts " Subject: #{data['subject']}"
61
+ puts " Template: #{data['template']}"
62
+ puts
63
+ end
64
+ end
65
+
66
+ class AnalyticsEventMessage < SmartMessage::Base
67
+ from 'various-services'
68
+ to 'analytics-service'
69
+
70
+ transport transport
71
+ serializer SmartMessage::Serializer::Json.new
72
+
73
+ property :event_type, required: true
74
+ property :user_id
75
+ property :metadata, default: {}
76
+ property :timestamp, default: -> { Time.now.iso8601 }
77
+
78
+ def self.process(wrapper)
79
+ header, payload = wrapper.split
80
+ data = JSON.parse(payload)
81
+
82
+ puts "📊 [ANALYTICS] Event: #{data['event_type']}"
83
+ puts " User: #{data['user_id'] || 'anonymous'}"
84
+ puts " Timestamp: #{data['timestamp']}"
85
+ puts " Metadata: #{data['metadata']}"
86
+ puts
87
+ end
88
+ end
89
+
90
+ class AdminAlertMessage < SmartMessage::Base
91
+ from 'monitoring'
92
+ to 'admin-panel'
93
+
94
+ transport transport
95
+ serializer SmartMessage::Serializer::Json.new
96
+
97
+ property :severity, required: true
98
+ property :message, required: true
99
+ property :service, required: true
100
+
101
+ def self.process(wrapper)
102
+ header, payload = wrapper.split
103
+ data = JSON.parse(payload)
104
+
105
+ puts "⚠️ [ADMIN PANEL] #{data['severity'].upcase} from #{data['service']}"
106
+ puts " #{data['message']}"
107
+ puts
108
+ end
109
+ end
110
+
111
+ #==============================================================================
112
+ # Fluent API Demonstration Functions
113
+ #==============================================================================
114
+
115
+ def demo_basic_fluent_subscriptions(transport)
116
+ puts "🔗 Setting up fluent API subscriptions..."
117
+ puts
118
+
119
+ # Basic fluent subscriptions
120
+ transport.where.from('web-app').subscribe
121
+ puts "✅ Subscribed to all messages FROM 'web-app'"
122
+
123
+ transport.where.to('user-service').subscribe
124
+ puts "✅ Subscribed to all messages TO 'user-service'"
125
+
126
+ transport.where.type('EmailNotificationMessage').subscribe
127
+ puts "✅ Subscribed to all 'EmailNotificationMessage' messages"
128
+ puts
129
+ end
130
+
131
+ def demo_combined_fluent_subscriptions(transport)
132
+ puts "🎯 Setting up combined fluent API subscriptions..."
133
+ puts
134
+
135
+ # Combined conditions
136
+ transport.where
137
+ .from('user-service')
138
+ .to('notification-service')
139
+ .subscribe
140
+ puts "✅ Subscribed to messages FROM 'user-service' TO 'notification-service'"
141
+
142
+ transport.where
143
+ .type('AnalyticsEventMessage')
144
+ .from('web-app')
145
+ .subscribe
146
+ puts "✅ Subscribed to 'AnalyticsEventMessage' FROM 'web-app'"
147
+
148
+ # Three-way combination
149
+ transport.where
150
+ .type('AdminAlertMessage')
151
+ .from('monitoring')
152
+ .to('admin-panel')
153
+ .subscribe
154
+ puts "✅ Subscribed to 'AdminAlertMessage' FROM 'monitoring' TO 'admin-panel'"
155
+ puts
156
+ end
157
+
158
+ def demo_wildcard_subscriptions(transport)
159
+ puts "🌟 Setting up wildcard pattern subscriptions..."
160
+ puts
161
+
162
+ # Service-specific patterns
163
+ transport.where.from('analytics-service').subscribe
164
+ puts "✅ Subscribed to all messages from analytics service"
165
+
166
+ transport.where.to('notification-service').subscribe
167
+ puts "✅ Subscribed to all messages to notification service"
168
+
169
+ # Catch-all analytics events
170
+ transport.where.type('AnalyticsEventMessage').subscribe
171
+ puts "✅ Subscribed to all analytics events regardless of source/destination"
172
+ puts
173
+ end
174
+
175
+ def publish_sample_workflow
176
+ puts "📤 Publishing sample microservices workflow..."
177
+ puts
178
+
179
+ # 1. User registration from web app
180
+ registration = UserRegistrationMessage.new(
181
+ user_id: 'user_12345',
182
+ email: 'john.doe@example.com',
183
+ name: 'John Doe'
184
+ )
185
+ registration.publish
186
+
187
+ sleep 0.1 # Small delay to see message processing order
188
+
189
+ # 2. Welcome email notification
190
+ welcome_email = EmailNotificationMessage.new(
191
+ recipient: 'john.doe@example.com',
192
+ subject: 'Welcome to Our Platform!',
193
+ body: 'Thank you for joining us, John!',
194
+ template: 'welcome'
195
+ )
196
+ welcome_email.publish
197
+
198
+ sleep 0.1
199
+
200
+ # 3. Analytics event from user service
201
+ analytics = AnalyticsEventMessage.new(
202
+ event_type: 'user_registered',
203
+ user_id: 'user_12345',
204
+ metadata: {
205
+ source: 'web_signup',
206
+ referrer: 'google_ads',
207
+ campaign: 'spring_2024'
208
+ }
209
+ )
210
+ analytics.from('user-service') # Override default 'from'
211
+ analytics.publish
212
+
213
+ sleep 0.1
214
+
215
+ # 4. Another analytics event from web-app
216
+ web_analytics = AnalyticsEventMessage.new(
217
+ event_type: 'signup_completed',
218
+ user_id: 'user_12345',
219
+ metadata: {
220
+ page: '/signup/complete',
221
+ time_spent: 45
222
+ }
223
+ )
224
+ web_analytics.from('web-app')
225
+ web_analytics.publish
226
+
227
+ sleep 0.1
228
+
229
+ # 5. Admin alert from monitoring
230
+ admin_alert = AdminAlertMessage.new(
231
+ severity: 'info',
232
+ message: 'New user registration completed successfully',
233
+ service: 'user-service'
234
+ )
235
+ admin_alert.publish
236
+
237
+ puts "✅ Published complete user registration workflow (5 messages)"
238
+ puts
239
+ end
240
+
241
+ def demonstrate_pattern_building(transport)
242
+ puts "🔨 Demonstrating pattern building..."
243
+ puts
244
+
245
+ # Show how patterns are built
246
+ builder = transport.where.from('web-app').to('user-service').type('UserRegistrationMessage')
247
+ pattern = builder.build
248
+ puts "Pattern for web-app → user-service UserRegistrationMessage:"
249
+ puts " #{pattern}"
250
+ puts
251
+
252
+ builder2 = transport.where.type('AnalyticsEventMessage')
253
+ pattern2 = builder2.build
254
+ puts "Pattern for any AnalyticsEventMessage:"
255
+ puts " #{pattern2}"
256
+ puts
257
+
258
+ builder3 = transport.where.from('monitoring')
259
+ pattern3 = builder3.build
260
+ puts "Pattern for any message from monitoring:"
261
+ puts " #{pattern3}"
262
+ puts
263
+ end
264
+
265
+ #==============================================================================
266
+ # Main Demonstration
267
+ #==============================================================================
268
+
269
+ begin
270
+ puts "🔧 Checking Redis connection..."
271
+ unless transport.connected?
272
+ puts "❌ Redis not available. Please start Redis server:"
273
+ puts " brew services start redis # macOS"
274
+ puts " sudo service redis start # Linux"
275
+ exit 1
276
+ end
277
+ puts "✅ Connected to Redis"
278
+ puts
279
+
280
+ # Demonstrate pattern building first
281
+ demonstrate_pattern_building(transport)
282
+
283
+ # Set up various fluent API subscriptions
284
+ demo_basic_fluent_subscriptions(transport)
285
+ demo_combined_fluent_subscriptions(transport)
286
+ demo_wildcard_subscriptions(transport)
287
+
288
+ # Subscribe message classes to their handlers
289
+ UserRegistrationMessage.subscribe
290
+ EmailNotificationMessage.subscribe
291
+ AnalyticsEventMessage.subscribe
292
+ AdminAlertMessage.subscribe
293
+
294
+ puts "⏳ Waiting for subscriptions to be established..."
295
+ sleep 1
296
+
297
+ # Publish sample workflow
298
+ publish_sample_workflow
299
+
300
+ puts "⏳ Processing messages (waiting 3 seconds)..."
301
+ sleep 3
302
+
303
+ # Show active patterns
304
+ puts "📋 Active Pattern Subscriptions:"
305
+ pattern_subscriptions = transport.instance_variable_get(:@pattern_subscriptions)
306
+ if pattern_subscriptions && pattern_subscriptions.any?
307
+ pattern_subscriptions.each_with_index do |pattern, i|
308
+ puts " #{i + 1}. #{pattern}"
309
+ end
310
+ else
311
+ puts " No pattern subscriptions found"
312
+ end
313
+ puts
314
+
315
+ puts "🎉 Fluent API Demo completed!"
316
+ puts "💡 Key takeaways:"
317
+ puts " • Fluent API makes complex subscriptions readable"
318
+ puts " • Combine .from(), .to(), and .type() for precise routing"
319
+ puts " • Patterns are built as: type.from.to with wildcards (*)"
320
+ puts " • Each .subscribe() call adds a new pattern to the transport"
321
+
322
+ rescue Interrupt
323
+ puts "\n👋 Demo interrupted by user"
324
+ rescue => e
325
+ puts "💥 Error: #{e.message}"
326
+ puts e.backtrace[0..3]
327
+ ensure
328
+ puts "\n🧹 Cleaning up..."
329
+ transport&.disconnect
330
+ puts "✅ Disconnected from Redis"
331
+ end
@@ -0,0 +1,281 @@
1
+ #!/usr/bin/env ruby
2
+ # examples/redis_queue/enhanced_03_dual_publishing.rb
3
+ # Redis Enhanced Transport - Dual Channel Publishing Demo
4
+
5
+ require_relative '../../lib/smart_message'
6
+ require 'smart_message/transport/redis_enhanced_transport'
7
+
8
+ puts "🚀 Redis Enhanced Transport - Dual Channel Publishing Demo"
9
+ puts "=" * 58
10
+
11
+ # Create both enhanced and basic Redis transports to demonstrate compatibility
12
+ enhanced_transport = SmartMessage::Transport::RedisEnhancedTransport.new(
13
+ url: 'redis://localhost:6379',
14
+ db: 4, # Use database 4 for dual publishing examples
15
+ auto_subscribe: true
16
+ )
17
+
18
+ basic_transport = SmartMessage::Transport::RedisTransport.new(
19
+ url: 'redis://localhost:6379',
20
+ db: 4, # Same database to show cross-transport communication
21
+ auto_subscribe: true
22
+ )
23
+
24
+ #==============================================================================
25
+ # Define Message Classes for Both Transports
26
+ #==============================================================================
27
+
28
+ class OrderStatusMessage < SmartMessage::Base
29
+ from 'order-service'
30
+ to 'customer-notification'
31
+
32
+ transport enhanced_transport
33
+ serializer SmartMessage::Serializer::Json.new
34
+
35
+ property :order_id, required: true
36
+ property :status, required: true
37
+ property :customer_email, required: true
38
+ property :updated_at, default: -> { Time.now.iso8601 }
39
+
40
+ def self.process(wrapper)
41
+ header, payload = wrapper.split
42
+ data = JSON.parse(payload)
43
+
44
+ puts "📋 [ENHANCED] Order #{data['order_id']} status: #{data['status']}"
45
+ puts " Customer: #{data['customer_email']}"
46
+ puts " Channel: Enhanced (dual publishing)"
47
+ puts " From: #{header.from} → To: #{header.to}"
48
+ puts
49
+ end
50
+ end
51
+
52
+ # Same message class but using basic transport
53
+ class LegacyOrderMessage < SmartMessage::Base
54
+ from 'legacy-system'
55
+
56
+ transport basic_transport
57
+ serializer SmartMessage::Serializer::Json.new
58
+
59
+ property :order_id, required: true
60
+ property :action, required: true
61
+ property :details, default: {}
62
+
63
+ def self.process(wrapper)
64
+ header, payload = wrapper.split
65
+ data = JSON.parse(payload)
66
+
67
+ puts "🔄 [BASIC] Legacy order #{data['order_id']} - #{data['action']}"
68
+ puts " Channel: Basic (single channel)"
69
+ puts " From: #{header.from}"
70
+ puts
71
+ end
72
+ end
73
+
74
+ # Message that demonstrates backwards compatibility
75
+ class CompatibilityTestMessage < SmartMessage::Base
76
+ from 'test-service'
77
+ to 'compatibility-test'
78
+
79
+ # Will be configured dynamically to test both transports
80
+ serializer SmartMessage::Serializer::Json.new
81
+
82
+ property :test_id, required: true
83
+ property :transport_type, required: true
84
+ property :message_content, required: true
85
+
86
+ def self.process(wrapper)
87
+ header, payload = wrapper.split
88
+ data = JSON.parse(payload)
89
+
90
+ puts "🧪 [#{data['transport_type'].upcase}] Test #{data['test_id']}"
91
+ puts " Content: #{data['message_content']}"
92
+ puts " From: #{header.from} → To: #{header.to}"
93
+ puts
94
+ end
95
+ end
96
+
97
+ #==============================================================================
98
+ # Demonstration Functions
99
+ #==============================================================================
100
+
101
+ def demonstrate_dual_publishing
102
+ puts "🔄 Demonstrating dual channel publishing..."
103
+ puts "Enhanced transport publishes to BOTH channels:"
104
+ puts " 1. Original channel: 'OrderStatusMessage'"
105
+ puts " 2. Enhanced channel: 'orderstatusmessage.order_service.customer_notification'"
106
+ puts
107
+
108
+ # Publish enhanced message
109
+ order_status = OrderStatusMessage.new(
110
+ order_id: 'ORD-2024-001',
111
+ status: 'shipped',
112
+ customer_email: 'customer@example.com'
113
+ )
114
+
115
+ puts "📤 Publishing OrderStatusMessage (enhanced transport)..."
116
+ order_status.publish
117
+ puts "✅ Message published to both original and enhanced channels"
118
+ puts
119
+ end
120
+
121
+ def demonstrate_backwards_compatibility
122
+ puts "🔙 Demonstrating backwards compatibility..."
123
+ puts "Enhanced transport should receive messages from basic transport"
124
+ puts
125
+
126
+ # Publish from basic transport
127
+ legacy_message = LegacyOrderMessage.new(
128
+ order_id: 'ORD-LEGACY-001',
129
+ action: 'processed',
130
+ details: { processor: 'legacy_v1.2', timestamp: Time.now.to_i }
131
+ )
132
+
133
+ puts "📤 Publishing from basic Redis transport..."
134
+ legacy_message.publish
135
+ puts "✅ Basic transport message published"
136
+ puts
137
+ end
138
+
139
+ def demonstrate_cross_transport_subscriptions(enhanced_transport)
140
+ puts "🌉 Setting up cross-transport subscriptions..."
141
+ puts
142
+
143
+ # Enhanced transport subscribes to basic transport patterns
144
+ enhanced_transport.subscribe_pattern("LegacyOrderMessage") # Basic channel name
145
+ enhanced_transport.subscribe_pattern("*.legacy_system.*") # Enhanced pattern that won't match basic
146
+
147
+ puts "✅ Enhanced transport subscribed to:"
148
+ puts " • 'LegacyOrderMessage' (basic channel)"
149
+ puts " • '*.legacy_system.*' (enhanced pattern)"
150
+ puts
151
+ end
152
+
153
+ def test_transport_compatibility
154
+ puts "🧪 Testing transport compatibility..."
155
+ puts
156
+
157
+ # Test 1: Enhanced message with enhanced transport
158
+ CompatibilityTestMessage.config { transport enhanced_transport }
159
+
160
+ enhanced_test = CompatibilityTestMessage.new(
161
+ test_id: 'TEST-001',
162
+ transport_type: 'enhanced',
163
+ message_content: 'Testing dual channel publishing'
164
+ )
165
+
166
+ puts "📤 Test 1: Enhanced transport with enhanced message..."
167
+ enhanced_test.publish
168
+
169
+ # Test 2: Basic message with basic transport
170
+ CompatibilityTestMessage.config { transport basic_transport }
171
+
172
+ basic_test = CompatibilityTestMessage.new(
173
+ test_id: 'TEST-002',
174
+ transport_type: 'basic',
175
+ message_content: 'Testing single channel publishing'
176
+ )
177
+
178
+ puts "📤 Test 2: Basic transport with basic message..."
179
+ basic_test.publish
180
+ puts
181
+ end
182
+
183
+ def show_channel_comparison
184
+ puts "📊 Channel Comparison:"
185
+ puts "┌─────────────────┬───────────────────────┬────────────────────────────────────┐"
186
+ puts "│ Transport Type │ Original Channel │ Enhanced Channel │"
187
+ puts "├─────────────────┼───────────────────────┼────────────────────────────────────┤"
188
+ puts "│ Basic │ MessageClassName │ (none) │"
189
+ puts "│ Enhanced │ MessageClassName │ messageclassname.from.to │"
190
+ puts "└─────────────────┴───────────────────────┴────────────────────────────────────┘"
191
+ puts
192
+
193
+ puts "📋 Pattern Matching Examples:"
194
+ puts "• Basic pattern: 'OrderStatusMessage'"
195
+ puts "• Enhanced pattern: 'orderstatusmessage.order_service.customer_notification'"
196
+ puts "• Wildcard pattern: '*.order_service.*' (matches all from order-service)"
197
+ puts "• Type pattern: 'orderstatusmessage.*.*' (matches all order status messages)"
198
+ puts
199
+ end
200
+
201
+ def monitor_redis_channels
202
+ puts "👀 Monitoring Redis channels (simulation)..."
203
+ puts "If you were monitoring Redis, you would see:"
204
+ puts
205
+ puts "BASIC TRANSPORT publishes to:"
206
+ puts " ├─ 'LegacyOrderMessage'"
207
+ puts " └─ 'CompatibilityTestMessage'"
208
+ puts
209
+ puts "ENHANCED TRANSPORT publishes to:"
210
+ puts " ├─ 'OrderStatusMessage' (backwards compatibility)"
211
+ puts " ├─ 'orderstatusmessage.order_service.customer_notification' (enhanced)"
212
+ puts " ├─ 'CompatibilityTestMessage' (backwards compatibility)"
213
+ puts " └─ 'compatibilitytestmessage.test_service.compatibility_test' (enhanced)"
214
+ puts
215
+ end
216
+
217
+ #==============================================================================
218
+ # Main Demonstration
219
+ #==============================================================================
220
+
221
+ begin
222
+ puts "🔧 Checking Redis connections..."
223
+ unless enhanced_transport.connected? && basic_transport.connected?
224
+ puts "❌ Redis not available. Please start Redis server:"
225
+ puts " brew services start redis # macOS"
226
+ puts " sudo service redis start # Linux"
227
+ exit 1
228
+ end
229
+ puts "✅ Connected to Redis (both transports)"
230
+ puts
231
+
232
+ # Show channel comparison
233
+ show_channel_comparison
234
+
235
+ # Set up cross-transport subscriptions
236
+ demonstrate_cross_transport_subscriptions(enhanced_transport)
237
+
238
+ # Subscribe message classes
239
+ OrderStatusMessage.subscribe
240
+ LegacyOrderMessage.subscribe
241
+ CompatibilityTestMessage.subscribe
242
+
243
+ puts "⏳ Waiting for subscriptions to be established..."
244
+ sleep 1
245
+
246
+ # Run demonstrations
247
+ demonstrate_dual_publishing
248
+ sleep 0.5
249
+
250
+ demonstrate_backwards_compatibility
251
+ sleep 0.5
252
+
253
+ test_transport_compatibility
254
+ sleep 1
255
+
256
+ puts "⏳ Processing messages (waiting 3 seconds)..."
257
+ sleep 3
258
+
259
+ # Show monitoring simulation
260
+ monitor_redis_channels
261
+
262
+ puts "🎉 Dual Publishing Demo completed!"
263
+ puts
264
+ puts "💡 Key Insights:"
265
+ puts " • Enhanced transport publishes to BOTH original and enhanced channels"
266
+ puts " • This provides backwards compatibility with basic Redis transport"
267
+ puts " • Enhanced patterns allow more sophisticated routing"
268
+ puts " • Basic transport only publishes to original channels"
269
+ puts " • Both transports can coexist and communicate"
270
+
271
+ rescue Interrupt
272
+ puts "\n👋 Demo interrupted by user"
273
+ rescue => e
274
+ puts "💥 Error: #{e.message}"
275
+ puts e.backtrace[0..3]
276
+ ensure
277
+ puts "\n🧹 Cleaning up..."
278
+ enhanced_transport&.disconnect
279
+ basic_transport&.disconnect
280
+ puts "✅ Disconnected from Redis (both transports)"
281
+ end