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,422 @@
1
+ #!/usr/bin/env ruby
2
+ # examples/redis_queue/03_fluent_api.rb
3
+ # Demonstration of the Fluent API for Redis Queue Transport
4
+
5
+ require_relative '../../lib/smart_message'
6
+ require 'async'
7
+
8
+ puts "🎨 Redis Queue Transport - Fluent API Demo"
9
+ puts "=" * 50
10
+
11
+ #==============================================================================
12
+ # Transport Setup
13
+ #==============================================================================
14
+
15
+ transport = SmartMessage::Transport::RedisQueueTransport.new(
16
+ url: 'redis://localhost:6379',
17
+ db: 3, # Use database 3 for fluent API examples
18
+ queue_prefix: 'fluent_demo',
19
+ exchange_name: 'smart_message',
20
+ consumer_timeout: 1, # 1 second timeout
21
+ test_mode: false # Enable consumer tasks
22
+ )
23
+
24
+ #==============================================================================
25
+ # Message Classes
26
+ #==============================================================================
27
+
28
+ class TaskMessage < SmartMessage::Base
29
+ transport :redis_queue, {
30
+ url: 'redis://localhost:6379',
31
+ db: 3,
32
+ queue_prefix: 'fluent_demo',
33
+ exchange_name: 'smart_message',
34
+ test_mode: false
35
+ }
36
+
37
+ property :task_id, required: true
38
+ property :task_type, required: true
39
+ property :assigned_to
40
+ property :priority, default: 'medium'
41
+ property :estimated_hours, default: 1
42
+
43
+ def process
44
+ priority_icon = case priority
45
+ when 'critical' then '🔥'
46
+ when 'high' then '⚡'
47
+ when 'medium' then '⚖️'
48
+ when 'low' then '🐌'
49
+ else '📝'
50
+ end
51
+
52
+ puts "#{priority_icon} Task #{task_id} [#{task_type}] → #{assigned_to} (#{estimated_hours}h)"
53
+ end
54
+ end
55
+
56
+ class EventMessage < SmartMessage::Base
57
+ transport :redis_queue, {
58
+ url: 'redis://localhost:6379',
59
+ db: 3,
60
+ queue_prefix: 'fluent_demo',
61
+ exchange_name: 'smart_message',
62
+ test_mode: false
63
+ }
64
+
65
+ property :event_type, required: true
66
+ property :user_id
67
+ property :session_id
68
+ property :metadata, default: {}
69
+ property :timestamp, default: -> { Time.now }
70
+
71
+ def process
72
+ puts "📈 Event: #{event_type} | User: #{user_id} | Session: #{session_id}"
73
+ puts " Metadata: #{metadata.inspect}" if metadata.any?
74
+ end
75
+ end
76
+
77
+ class AlertMessage < SmartMessage::Base
78
+ transport :redis_queue, {
79
+ url: 'redis://localhost:6379',
80
+ db: 3,
81
+ queue_prefix: 'fluent_demo',
82
+ exchange_name: 'smart_message',
83
+ test_mode: false
84
+ }
85
+
86
+ property :alert_id, required: true
87
+ property :service, required: true
88
+ property :level, required: true
89
+ property :description, required: true
90
+ property :tags, default: []
91
+
92
+ def process
93
+ level_icon = case level
94
+ when 'critical' then '🚨'
95
+ when 'warning' then '⚠️'
96
+ when 'info' then 'ℹ️'
97
+ else '📢'
98
+ end
99
+
100
+ puts "#{level_icon} Alert #{alert_id}: #{service} - #{description}"
101
+ puts " Tags: #{tags.join(', ')}" if tags.any?
102
+ end
103
+ end
104
+
105
+ #==============================================================================
106
+ # Fluent API Subscription Examples
107
+ #==============================================================================
108
+
109
+ Async do
110
+ puts "\n🎭 Setting up Fluent API subscriptions:"
111
+
112
+ # Example 1: Simple FROM subscription
113
+ puts "1️⃣ Subscribe to messages FROM 'api_service'"
114
+ subscription1 = transport.where
115
+ .from('api_service')
116
+ .subscribe do |message_class, message_data|
117
+ data = JSON.parse(message_data)
118
+ puts "🔵 API Service Message: #{message_class} - #{data['task_id'] || data['event_type'] || data['alert_id']}"
119
+ end
120
+
121
+ # Example 2: Simple TO subscription
122
+ puts "2️⃣ Subscribe to messages TO 'task_processor'"
123
+ subscription2 = transport.where
124
+ .to('task_processor')
125
+ .subscribe do |message_class, message_data|
126
+ data = JSON.parse(message_data)
127
+ puts "🟢 Task Processor: #{message_class} - #{data['task_id'] || data['task_type']}"
128
+ end
129
+
130
+ # Example 3: Type-specific subscription
131
+ puts "3️⃣ Subscribe to TaskMessage types only"
132
+ subscription3 = transport.where
133
+ .type('TaskMessage')
134
+ .subscribe do |message_class, message_data|
135
+ data = JSON.parse(message_data)
136
+ puts "📋 Task Only: #{data['task_id']} - #{data['task_type']} [#{data['priority']}]"
137
+ end
138
+
139
+ # Example 4: Combined FROM and TO
140
+ puts "4️⃣ Subscribe FROM 'web_app' TO 'event_processor'"
141
+ subscription4 = transport.where
142
+ .from('web_app')
143
+ .to('event_processor')
144
+ .subscribe do |message_class, message_data|
145
+ data = JSON.parse(message_data)
146
+ puts "🌐➡️📊 Web→Events: #{message_class} - #{data['event_type']}"
147
+ end
148
+
149
+ # Example 5: Consumer group with load balancing
150
+ puts "5️⃣ Subscribe with consumer group 'alert_handlers'"
151
+ subscription5 = transport.where
152
+ .type('AlertMessage')
153
+ .consumer_group('alert_handlers')
154
+ .subscribe do |message_class, message_data|
155
+ data = JSON.parse(message_data)
156
+ fiber_id = Async::Task.current.object_id.to_s[-4..-1]
157
+ puts "⚡ Fiber-#{fiber_id}: Alert #{data['alert_id']} [#{data['level']}]"
158
+ end
159
+
160
+ # Example 6: Complex multi-criteria subscription
161
+ puts "6️⃣ Subscribe FROM admin services TO monitoring with group"
162
+ subscription6 = transport.where
163
+ .from(/^admin_.*/) # Regex pattern for admin services
164
+ .to('monitoring_service')
165
+ .consumer_group('monitoring_workers')
166
+ .subscribe do |message_class, message_data|
167
+ data = JSON.parse(message_data)
168
+ puts "👑📊 Admin→Monitor: #{message_class}"
169
+ end
170
+
171
+ # Example 7: Type and destination combination
172
+ puts "7️⃣ Subscribe to EventMessage TO analytics services"
173
+ subscription7 = transport.where
174
+ .type('EventMessage')
175
+ .to(/.*analytics.*/) # Any service with 'analytics' in name
176
+ .subscribe do |message_class, message_data|
177
+ data = JSON.parse(message_data)
178
+ puts "📈🎯 Events→Analytics: #{data['event_type']} - User #{data['user_id']}"
179
+ end
180
+
181
+ # Wait for subscriptions to initialize
182
+ sleep 1
183
+
184
+ #============================================================================
185
+ # Pattern Building Demonstration
186
+ #============================================================================
187
+
188
+ puts "\n🏗️ Pattern Building Examples:"
189
+
190
+ # Show how different fluent combinations create patterns
191
+ builders = [
192
+ transport.where.from('api_service'),
193
+ transport.where.to('task_processor'),
194
+ transport.where.type('TaskMessage'),
195
+ transport.where.from('web_app').to('event_processor'),
196
+ transport.where.type('AlertMessage').from('monitoring'),
197
+ transport.where.to('analytics_service').type('EventMessage')
198
+ ]
199
+
200
+ builders.each_with_index do |builder, i|
201
+ pattern = builder.build
202
+ puts "#{i + 1}. Pattern: '#{pattern}'"
203
+ end
204
+
205
+ #============================================================================
206
+ # Message Publishing Examples
207
+ #============================================================================
208
+
209
+ puts "\n📤 Publishing messages to demonstrate fluent subscriptions:"
210
+
211
+ # Messages FROM api_service (triggers subscription 1)
212
+ puts "\n🔸 Messages FROM api_service:"
213
+ TaskMessage.new(
214
+ task_id: 'TASK-001',
215
+ task_type: 'data_processing',
216
+ assigned_to: 'task_processor',
217
+ priority: 'high',
218
+ _sm_header: { from: 'api_service', to: 'task_processor' }
219
+ ).publish
220
+
221
+ EventMessage.new(
222
+ event_type: 'api_call',
223
+ user_id: 'user123',
224
+ session_id: 'sess456',
225
+ metadata: { endpoint: '/api/tasks', method: 'POST' },
226
+ _sm_header: { from: 'api_service', to: 'analytics_service' }
227
+ ).publish
228
+
229
+ # Messages TO task_processor (triggers subscription 2)
230
+ puts "\n🔸 Messages TO task_processor:"
231
+ TaskMessage.new(
232
+ task_id: 'TASK-002',
233
+ task_type: 'image_processing',
234
+ assigned_to: 'task_processor',
235
+ priority: 'medium',
236
+ estimated_hours: 3,
237
+ _sm_header: { from: 'upload_service', to: 'task_processor' }
238
+ ).publish
239
+
240
+ TaskMessage.new(
241
+ task_id: 'TASK-003',
242
+ task_type: 'email_processing',
243
+ assigned_to: 'task_processor',
244
+ priority: 'low',
245
+ _sm_header: { from: 'mail_service', to: 'task_processor' }
246
+ ).publish
247
+
248
+ # TaskMessage types (triggers subscription 3)
249
+ puts "\n🔸 Various TaskMessage types:"
250
+ TaskMessage.new(
251
+ task_id: 'TASK-004',
252
+ task_type: 'backup_database',
253
+ assigned_to: 'backup_service',
254
+ priority: 'critical',
255
+ estimated_hours: 2,
256
+ _sm_header: { from: 'scheduler', to: 'backup_service' }
257
+ ).publish
258
+
259
+ # Web app to event processor (triggers subscription 4)
260
+ puts "\n🔸 Web app to event processor:"
261
+ EventMessage.new(
262
+ event_type: 'page_view',
263
+ user_id: 'user789',
264
+ session_id: 'sess123',
265
+ metadata: { page: '/dashboard', referrer: '/login' },
266
+ _sm_header: { from: 'web_app', to: 'event_processor' }
267
+ ).publish
268
+
269
+ EventMessage.new(
270
+ event_type: 'button_click',
271
+ user_id: 'user789',
272
+ session_id: 'sess123',
273
+ metadata: { button_id: 'save_profile', page: '/settings' },
274
+ _sm_header: { from: 'web_app', to: 'event_processor' }
275
+ ).publish
276
+
277
+ # Alert messages for consumer groups (triggers subscription 5)
278
+ puts "\n🔸 Alert messages for load balancing:"
279
+ 3.times do |i|
280
+ AlertMessage.new(
281
+ alert_id: "ALERT-#{sprintf('%03d', i + 1)}",
282
+ service: ['database', 'cache', 'api'][i],
283
+ level: ['critical', 'warning', 'info'][i],
284
+ description: ["Database connection lost", "Cache hit rate below 80%", "API response time normal"][i],
285
+ tags: [['db', 'urgent'], ['cache', 'performance'], ['api', 'info']][i],
286
+ _sm_header: { from: 'monitoring_service', to: 'alert_handler' }
287
+ ).publish
288
+ end
289
+
290
+ # Admin messages to monitoring (triggers subscription 6)
291
+ puts "\n🔸 Admin messages to monitoring:"
292
+ AlertMessage.new(
293
+ alert_id: 'ADMIN-001',
294
+ service: 'user_management',
295
+ level: 'info',
296
+ description: 'User privileges updated for admin user',
297
+ tags: ['admin', 'security'],
298
+ _sm_header: { from: 'admin_panel', to: 'monitoring_service' }
299
+ ).publish
300
+
301
+ EventMessage.new(
302
+ event_type: 'admin_action',
303
+ user_id: 'admin123',
304
+ metadata: { action: 'user_created', target_user: 'newuser456' },
305
+ _sm_header: { from: 'admin_service', to: 'monitoring_service' }
306
+ ).publish
307
+
308
+ # Event messages to analytics (triggers subscription 7)
309
+ puts "\n🔸 Event messages to analytics services:"
310
+ EventMessage.new(
311
+ event_type: 'purchase_completed',
312
+ user_id: 'customer123',
313
+ session_id: 'shop_session_789',
314
+ metadata: { order_id: 'ORD-789', amount: 149.99, items: 3 },
315
+ _sm_header: { from: 'checkout_service', to: 'user_analytics' }
316
+ ).publish
317
+
318
+ EventMessage.new(
319
+ event_type: 'search_query',
320
+ user_id: 'customer456',
321
+ metadata: { query: 'wireless headphones', results: 24 },
322
+ _sm_header: { from: 'search_service', to: 'search_analytics' }
323
+ ).publish
324
+
325
+ # Wait for message processing
326
+ puts "\n⏳ Processing all messages..."
327
+ sleep 5
328
+
329
+ #============================================================================
330
+ # Chained Fluent API Examples
331
+ #============================================================================
332
+
333
+ puts "\n🔗 Advanced Fluent API Chaining:"
334
+
335
+ # Example of building and modifying subscriptions
336
+ puts "\n8️⃣ Dynamic subscription building:"
337
+ base_subscription = transport.where.type('TaskMessage')
338
+
339
+ # Add criteria dynamically
340
+ urgent_tasks = base_subscription.from('urgent_processor')
341
+ pattern1 = urgent_tasks.build
342
+ puts "Dynamic pattern 1: #{pattern1}"
343
+
344
+ # Build different variations
345
+ analytics_tasks = base_subscription.to(/.*analytics.*/)
346
+ pattern2 = analytics_tasks.build
347
+ puts "Dynamic pattern 2: #{pattern2}"
348
+
349
+ # Complex chaining
350
+ complex_subscription = transport.where
351
+ .type('EventMessage')
352
+ .from(/^(web|mobile)_app$/) # From web or mobile app
353
+ .to(/.*analytics.*/) # To any analytics service
354
+ .consumer_group('analytics_processors')
355
+
356
+ pattern3 = complex_subscription.build
357
+ puts "Complex pattern: #{pattern3}"
358
+
359
+ # Subscribe with the complex pattern
360
+ complex_subscription.subscribe do |message_class, message_data|
361
+ data = JSON.parse(message_data)
362
+ puts "🎯 Complex Match: #{data['event_type']} from mobile/web → analytics"
363
+ end
364
+
365
+ # Test the complex subscription
366
+ EventMessage.new(
367
+ event_type: 'app_launch',
368
+ user_id: 'mobile_user123',
369
+ metadata: { platform: 'iOS', version: '2.1.0' },
370
+ _sm_header: { from: 'mobile_app', to: 'mobile_analytics' }
371
+ ).publish
372
+
373
+ sleep 2
374
+
375
+ #============================================================================
376
+ # Subscription Management
377
+ #============================================================================
378
+
379
+ puts "\n📊 Fluent API Statistics:"
380
+
381
+ # Show routing table
382
+ routing_table = transport.routing_table
383
+ puts "\nRouting patterns created by fluent API:"
384
+ routing_table.each_with_index do |(pattern, queues), i|
385
+ puts "#{i + 1}. '#{pattern}' → #{queues.size} queue(s)"
386
+ end
387
+
388
+ # Show queue statistics
389
+ stats = transport.queue_stats
390
+ puts "\nQueue statistics:"
391
+ total_messages = 0
392
+ stats.each do |queue_name, info|
393
+ total_messages += info[:length]
394
+ puts " #{queue_name}: #{info[:length]} messages"
395
+ end
396
+
397
+ puts "\nTotal messages in all queues: #{total_messages}"
398
+
399
+ # Cleanup
400
+ transport.disconnect
401
+ end
402
+
403
+ puts "\n🎨 Fluent API demonstration completed!"
404
+
405
+ puts "\n💡 Fluent API Features Demonstrated:"
406
+ puts " ✓ .from() - Source-based filtering"
407
+ puts " ✓ .to() - Destination-based filtering"
408
+ puts " ✓ .type() - Message type filtering"
409
+ puts " ✓ .consumer_group() - Load balancing"
410
+ puts " ✓ Method chaining for complex criteria"
411
+ puts " ✓ Regex patterns in from/to filters"
412
+ puts " ✓ Dynamic subscription building"
413
+ puts " ✓ Pattern generation and inspection"
414
+
415
+ puts "\n🚀 Key Benefits:"
416
+ puts " • Readable, expressive subscription syntax"
417
+ puts " • Type-safe subscription building"
418
+ puts " • Flexible criteria combination"
419
+ puts " • Runtime pattern inspection"
420
+ puts " • Easy consumer group management with Async fibers"
421
+ puts " • Complex routing made simple"
422
+ puts " • Fiber-based concurrency for massive scalability"