smart_message 0.0.10 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/deploy-github-pages.yml +38 -0
- data/.gitignore +5 -0
- data/CHANGELOG.md +30 -0
- data/Gemfile.lock +35 -4
- data/README.md +169 -71
- data/Rakefile +29 -4
- data/docs/assets/images/ddq_architecture.svg +130 -0
- data/docs/assets/images/dlq_architecture.svg +115 -0
- data/docs/assets/images/enhanced-dual-publishing.svg +136 -0
- data/docs/assets/images/enhanced-fluent-api.svg +149 -0
- data/docs/assets/images/enhanced-microservices-routing.svg +115 -0
- data/docs/assets/images/enhanced-pattern-matching.svg +107 -0
- data/docs/assets/images/fluent-api-demo.svg +59 -0
- data/docs/assets/images/performance-comparison.svg +161 -0
- data/docs/assets/images/redis-basic-architecture.svg +53 -0
- data/docs/assets/images/redis-enhanced-architecture.svg +88 -0
- data/docs/assets/images/redis-queue-architecture.svg +101 -0
- data/docs/assets/images/smart_message.jpg +0 -0
- data/docs/assets/images/smart_message_walking.jpg +0 -0
- data/docs/assets/images/smartmessage_architecture_overview.svg +173 -0
- data/docs/assets/images/transport-comparison-matrix.svg +171 -0
- data/docs/assets/javascripts/mathjax.js +17 -0
- data/docs/assets/stylesheets/extra.css +51 -0
- data/docs/{addressing.md → core-concepts/addressing.md} +5 -7
- data/docs/{architecture.md → core-concepts/architecture.md} +78 -138
- data/docs/{dispatcher.md → core-concepts/dispatcher.md} +21 -21
- data/docs/{message_filtering.md → core-concepts/message-filtering.md} +2 -3
- data/docs/{message_processing.md → core-concepts/message-processing.md} +17 -17
- data/docs/{troubleshooting.md → development/troubleshooting.md} +7 -7
- data/docs/{examples.md → getting-started/examples.md} +115 -89
- data/docs/{getting-started.md → getting-started/quick-start.md} +47 -18
- data/docs/guides/redis-queue-getting-started.md +697 -0
- data/docs/guides/redis-queue-patterns.md +889 -0
- data/docs/guides/redis-queue-production.md +1091 -0
- data/docs/index.md +64 -0
- data/docs/{dead_letter_queue.md → reference/dead-letter-queue.md} +2 -3
- data/docs/{logging.md → reference/logging.md} +1 -1
- data/docs/{message_deduplication.md → reference/message-deduplication.md} +1 -0
- data/docs/{proc_handlers_summary.md → reference/proc-handlers.md} +7 -6
- data/docs/{serializers.md → reference/serializers.md} +3 -5
- data/docs/{transports.md → reference/transports.md} +133 -11
- data/docs/transports/memory-transport.md +374 -0
- data/docs/transports/redis-enhanced-transport.md +524 -0
- data/docs/transports/redis-queue-transport.md +1304 -0
- data/docs/transports/redis-transport-comparison.md +496 -0
- data/docs/transports/redis-transport.md +509 -0
- data/examples/README.md +98 -5
- data/examples/city_scenario/911_emergency_call_flow.svg +99 -0
- data/examples/city_scenario/README.md +515 -0
- data/examples/city_scenario/ai_visitor_intelligence_flow.svg +108 -0
- data/examples/city_scenario/citizen.rb +195 -0
- data/examples/city_scenario/city_diagram.svg +125 -0
- data/examples/city_scenario/common/health_monitor.rb +80 -0
- data/examples/city_scenario/common/logger.rb +30 -0
- data/examples/city_scenario/emergency_dispatch_center.rb +270 -0
- data/examples/city_scenario/fire_department.rb +446 -0
- data/examples/city_scenario/fire_emergency_flow.svg +95 -0
- data/examples/city_scenario/health_department.rb +100 -0
- data/examples/city_scenario/health_monitoring_system.svg +130 -0
- data/examples/city_scenario/house.rb +244 -0
- data/examples/city_scenario/local_bank.rb +217 -0
- data/examples/city_scenario/messages/emergency_911_message.rb +81 -0
- data/examples/city_scenario/messages/emergency_resolved_message.rb +43 -0
- data/examples/city_scenario/messages/fire_dispatch_message.rb +43 -0
- data/examples/city_scenario/messages/fire_emergency_message.rb +45 -0
- data/examples/city_scenario/messages/health_check_message.rb +22 -0
- data/examples/city_scenario/messages/health_status_message.rb +35 -0
- data/examples/city_scenario/messages/police_dispatch_message.rb +46 -0
- data/examples/city_scenario/messages/silent_alarm_message.rb +38 -0
- data/examples/city_scenario/police_department.rb +316 -0
- data/examples/city_scenario/redis_monitor.rb +129 -0
- data/examples/city_scenario/redis_stats.rb +743 -0
- data/examples/city_scenario/room_for_improvement.md +240 -0
- data/examples/city_scenario/security_emergency_flow.svg +95 -0
- data/examples/city_scenario/service_internal_architecture.svg +154 -0
- data/examples/city_scenario/smart_message_ai_agent.rb +364 -0
- data/examples/city_scenario/start_demo.sh +236 -0
- data/examples/city_scenario/stop_demo.sh +106 -0
- data/examples/city_scenario/visitor.rb +631 -0
- data/examples/{10_message_deduplication.rb → memory/01_message_deduplication_demo.rb} +1 -1
- data/examples/{09_dead_letter_queue_demo.rb → memory/02_dead_letter_queue_demo.rb} +13 -40
- data/examples/{01_point_to_point_orders.rb → memory/03_point_to_point_orders.rb} +1 -1
- data/examples/{02_publish_subscribe_events.rb → memory/04_publish_subscribe_events.rb} +2 -2
- data/examples/{03_many_to_many_chat.rb → memory/05_many_to_many_chat.rb} +4 -4
- data/examples/{show_me.rb → memory/06_pretty_print_demo.rb} +1 -1
- data/examples/{05_proc_handlers.rb → memory/07_proc_handlers_demo.rb} +2 -2
- data/examples/{06_custom_logger_example.rb → memory/08_custom_logger_demo.rb} +17 -14
- data/examples/{07_error_handling_scenarios.rb → memory/09_error_handling_demo.rb} +4 -4
- data/examples/{08_entity_addressing_basic.rb → memory/10_entity_addressing_basic.rb} +8 -8
- data/examples/{08_entity_addressing_with_filtering.rb → memory/11_entity_addressing_with_filtering.rb} +6 -6
- data/examples/{09_regex_filtering_microservices.rb → memory/12_regex_filtering_microservices.rb} +2 -2
- data/examples/{10_header_block_configuration.rb → memory/13_header_block_configuration.rb} +6 -6
- data/examples/{11_global_configuration_example.rb → memory/14_global_configuration_demo.rb} +19 -8
- data/examples/{show_logger.rb → memory/15_logger_demo.rb} +1 -1
- data/examples/memory/README.md +163 -0
- data/examples/memory/memory_transport_architecture.svg +90 -0
- data/examples/memory/point_to_point_pattern.svg +94 -0
- data/examples/memory/publish_subscribe_pattern.svg +125 -0
- data/examples/{04_redis_smart_home_iot.rb → redis/01_smart_home_iot_demo.rb} +5 -5
- data/examples/redis/README.md +230 -0
- data/examples/redis/alert_system_flow.svg +127 -0
- data/examples/redis/dashboard_status_flow.svg +107 -0
- data/examples/redis/device_command_flow.svg +113 -0
- data/examples/redis/redis_transport_architecture.svg +115 -0
- data/examples/{smart_home_iot_dataflow.md → redis/smart_home_iot_dataflow.md} +4 -116
- data/examples/redis/smart_home_system_architecture.svg +133 -0
- data/examples/redis_enhanced/README.md +319 -0
- data/examples/redis_enhanced/enhanced_01_basic_patterns.rb +233 -0
- data/examples/redis_enhanced/enhanced_02_fluent_api.rb +331 -0
- data/examples/redis_enhanced/enhanced_03_dual_publishing.rb +281 -0
- data/examples/redis_enhanced/enhanced_04_advanced_routing.rb +419 -0
- data/examples/redis_queue/01_basic_messaging.rb +221 -0
- data/examples/redis_queue/01_comprehensive_examples.rb +508 -0
- data/examples/redis_queue/02_pattern_routing.rb +405 -0
- data/examples/redis_queue/03_fluent_api.rb +422 -0
- data/examples/redis_queue/04_load_balancing.rb +486 -0
- data/examples/redis_queue/05_microservices.rb +735 -0
- data/examples/redis_queue/06_emergency_alerts.rb +777 -0
- data/examples/redis_queue/07_queue_management.rb +587 -0
- data/examples/redis_queue/README.md +366 -0
- data/examples/redis_queue/enhanced_01_basic_patterns.rb +233 -0
- data/examples/redis_queue/enhanced_02_fluent_api.rb +331 -0
- data/examples/redis_queue/enhanced_03_dual_publishing.rb +281 -0
- data/examples/redis_queue/enhanced_04_advanced_routing.rb +419 -0
- data/examples/redis_queue/redis_queue_architecture.svg +148 -0
- data/ideas/README.md +41 -0
- data/ideas/agents.md +1001 -0
- data/ideas/database_transport.md +980 -0
- data/ideas/improvement.md +359 -0
- data/ideas/meshage.md +1788 -0
- data/ideas/message_discovery.md +178 -0
- data/ideas/message_schema.md +1381 -0
- data/lib/smart_message/.idea/.gitignore +8 -0
- data/lib/smart_message/.idea/markdown.xml +6 -0
- data/lib/smart_message/.idea/misc.xml +4 -0
- data/lib/smart_message/.idea/modules.xml +8 -0
- data/lib/smart_message/.idea/smart_message.iml +16 -0
- data/lib/smart_message/.idea/vcs.xml +6 -0
- data/lib/smart_message/addressing.rb +15 -0
- data/lib/smart_message/base.rb +0 -2
- data/lib/smart_message/configuration.rb +1 -1
- data/lib/smart_message/logger.rb +15 -4
- data/lib/smart_message/plugins.rb +5 -2
- data/lib/smart_message/serializer.rb +14 -0
- data/lib/smart_message/transport/redis_enhanced_transport.rb +399 -0
- data/lib/smart_message/transport/redis_queue_transport.rb +555 -0
- data/lib/smart_message/transport/registry.rb +1 -0
- data/lib/smart_message/transport.rb +34 -1
- data/lib/smart_message/version.rb +1 -1
- data/lib/smart_message.rb +5 -52
- data/mkdocs.yml +184 -0
- data/p2p_plan.md +326 -0
- data/p2p_roadmap.md +287 -0
- data/smart_message.gemspec +2 -0
- data/smart_message.svg +51 -0
- metadata +170 -44
- data/docs/README.md +0 -57
- data/examples/dead_letters.jsonl +0 -12
- data/examples/temp.txt +0 -94
- data/examples/tmux_chat/README.md +0 -283
- data/examples/tmux_chat/bot_agent.rb +0 -278
- data/examples/tmux_chat/human_agent.rb +0 -199
- data/examples/tmux_chat/room_monitor.rb +0 -160
- data/examples/tmux_chat/shared_chat_system.rb +0 -328
- data/examples/tmux_chat/start_chat_demo.sh +0 -190
- data/examples/tmux_chat/stop_chat_demo.sh +0 -22
- /data/docs/{properties.md → core-concepts/properties.md} +0 -0
- /data/docs/{ideas_to_think_about.md → development/ideas.md} +0 -0
@@ -0,0 +1,508 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# examples/redis_queue_transport_examples.rb
|
3
|
+
# Usage examples for RedisQueueTransport
|
4
|
+
|
5
|
+
require_relative '../../lib/smart_message'
|
6
|
+
|
7
|
+
# Configure Redis Queue transport
|
8
|
+
SmartMessage.configure do |config|
|
9
|
+
config.transport = :redis_queue
|
10
|
+
config.transport_options = {
|
11
|
+
url: 'redis://localhost:6379',
|
12
|
+
db: 0,
|
13
|
+
consumer_group: 'example_workers'
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
#==============================================================================
|
18
|
+
# Example 1: Basic Message Publishing and Subscription
|
19
|
+
#==============================================================================
|
20
|
+
|
21
|
+
class WelcomeMessage < SmartMessage::Base
|
22
|
+
transport :redis_queue
|
23
|
+
|
24
|
+
property :user_name, required: true
|
25
|
+
property :signup_date, default: -> { Time.now }
|
26
|
+
|
27
|
+
def process
|
28
|
+
puts "👋 Welcome #{user_name}! Account created on #{signup_date}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
puts "=== Example 1: Basic Usage ==="
|
33
|
+
|
34
|
+
# Subscribe to process welcome messages
|
35
|
+
WelcomeMessage.subscribe
|
36
|
+
|
37
|
+
# Publish a welcome message
|
38
|
+
WelcomeMessage.new(
|
39
|
+
user_name: 'Alice',
|
40
|
+
_sm_header: {
|
41
|
+
from: 'signup_service',
|
42
|
+
to: 'welcome_service'
|
43
|
+
}
|
44
|
+
).publish
|
45
|
+
|
46
|
+
sleep 2
|
47
|
+
|
48
|
+
#==============================================================================
|
49
|
+
# Example 2: Pattern-Based Subscriptions
|
50
|
+
#==============================================================================
|
51
|
+
|
52
|
+
class OrderMessage < SmartMessage::Base
|
53
|
+
transport :redis_queue
|
54
|
+
|
55
|
+
property :order_id, required: true
|
56
|
+
property :amount, required: true
|
57
|
+
property :customer_id, required: true
|
58
|
+
|
59
|
+
def process
|
60
|
+
puts "📦 Processing order #{order_id}: $#{amount} for customer #{customer_id}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
puts "\n=== Example 2: Pattern Subscriptions ==="
|
65
|
+
|
66
|
+
# Get transport instance for pattern subscriptions
|
67
|
+
transport = SmartMessage::Transport::RedisQueueTransport.new(
|
68
|
+
url: 'redis://localhost:6379',
|
69
|
+
consumer_group: 'order_processors'
|
70
|
+
)
|
71
|
+
|
72
|
+
# Subscribe to orders directed to fulfillment service
|
73
|
+
transport.subscribe_pattern("#.*.fulfillment_service") do |message_class, message_data|
|
74
|
+
message = JSON.parse(message_data)
|
75
|
+
puts "🏭 Fulfillment received: #{message_class} - #{message['order_id']}"
|
76
|
+
end
|
77
|
+
|
78
|
+
# Subscribe to orders from API gateway
|
79
|
+
transport.subscribe_pattern("#.api_gateway.*") do |message_class, message_data|
|
80
|
+
message = JSON.parse(message_data)
|
81
|
+
puts "🌐 API Gateway order: #{message_class} - #{message['order_id']}"
|
82
|
+
end
|
83
|
+
|
84
|
+
# Subscribe to all order messages regardless of routing
|
85
|
+
transport.subscribe_pattern("order.#.*.*") do |message_class, message_data|
|
86
|
+
message = JSON.parse(message_data)
|
87
|
+
puts "📋 Order audit log: #{message['order_id']} - $#{message['amount']}"
|
88
|
+
end
|
89
|
+
|
90
|
+
# Publish orders with different routing
|
91
|
+
OrderMessage.new(
|
92
|
+
order_id: 'ORD-001',
|
93
|
+
amount: 99.99,
|
94
|
+
customer_id: 'CUST-123',
|
95
|
+
_sm_header: {
|
96
|
+
from: 'api_gateway',
|
97
|
+
to: 'fulfillment_service'
|
98
|
+
}
|
99
|
+
).publish
|
100
|
+
|
101
|
+
OrderMessage.new(
|
102
|
+
order_id: 'ORD-002',
|
103
|
+
amount: 149.50,
|
104
|
+
customer_id: 'CUST-456',
|
105
|
+
_sm_header: {
|
106
|
+
from: 'mobile_app',
|
107
|
+
to: 'fulfillment_service'
|
108
|
+
}
|
109
|
+
).publish
|
110
|
+
|
111
|
+
sleep 3
|
112
|
+
|
113
|
+
#==============================================================================
|
114
|
+
# Example 3: Fluent API Usage
|
115
|
+
#==============================================================================
|
116
|
+
|
117
|
+
class NotificationMessage < SmartMessage::Base
|
118
|
+
transport :redis_queue
|
119
|
+
|
120
|
+
property :message_text, required: true
|
121
|
+
property :priority, default: 'normal'
|
122
|
+
property :user_id
|
123
|
+
|
124
|
+
def process
|
125
|
+
puts "🔔 Notification [#{priority}]: #{message_text}"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
puts "\n=== Example 3: Fluent API ==="
|
130
|
+
|
131
|
+
# Set up transport for fluent examples
|
132
|
+
notification_transport = SmartMessage::Transport::RedisQueueTransport.new(
|
133
|
+
url: 'redis://localhost:6379',
|
134
|
+
consumer_group: 'notification_workers'
|
135
|
+
)
|
136
|
+
|
137
|
+
# Subscribe to notifications for specific user
|
138
|
+
notification_transport.where
|
139
|
+
.type('NotificationMessage')
|
140
|
+
.to('user_123')
|
141
|
+
.consumer_group('user_notifications')
|
142
|
+
.subscribe do |message_class, message_data|
|
143
|
+
message = JSON.parse(message_data)
|
144
|
+
puts "👤 Personal notification for user_123: #{message['message_text']}"
|
145
|
+
end
|
146
|
+
|
147
|
+
# Subscribe to high priority notifications from admin
|
148
|
+
notification_transport.where
|
149
|
+
.from('admin_service')
|
150
|
+
.subscribe do |message_class, message_data|
|
151
|
+
message = JSON.parse(message_data)
|
152
|
+
puts "⚠️ Admin notification: #{message['message_text']}"
|
153
|
+
end
|
154
|
+
|
155
|
+
# Publish various notifications
|
156
|
+
NotificationMessage.new(
|
157
|
+
message_text: "Your order has shipped!",
|
158
|
+
priority: 'high',
|
159
|
+
user_id: 'user_123',
|
160
|
+
_sm_header: {
|
161
|
+
from: 'shipping_service',
|
162
|
+
to: 'user_123'
|
163
|
+
}
|
164
|
+
).publish
|
165
|
+
|
166
|
+
NotificationMessage.new(
|
167
|
+
message_text: "System maintenance scheduled for tonight",
|
168
|
+
priority: 'urgent',
|
169
|
+
_sm_header: {
|
170
|
+
from: 'admin_service',
|
171
|
+
to: 'broadcast'
|
172
|
+
}
|
173
|
+
).publish
|
174
|
+
|
175
|
+
sleep 2
|
176
|
+
|
177
|
+
#==============================================================================
|
178
|
+
# Example 4: Load Balancing with Consumer Groups
|
179
|
+
#==============================================================================
|
180
|
+
|
181
|
+
class WorkTask < SmartMessage::Base
|
182
|
+
transport :redis_queue
|
183
|
+
|
184
|
+
property :task_id, required: true
|
185
|
+
property :task_type, required: true
|
186
|
+
property :estimated_duration, default: 60
|
187
|
+
|
188
|
+
def process
|
189
|
+
puts "⚙️ Worker #{Thread.current.object_id} processing task #{task_id} (#{task_type})"
|
190
|
+
sleep(rand(1..3)) # Simulate work
|
191
|
+
puts "✅ Task #{task_id} completed by worker #{Thread.current.object_id}"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
puts "\n=== Example 4: Load Balanced Workers ==="
|
196
|
+
|
197
|
+
# Create multiple workers sharing same consumer group
|
198
|
+
worker_transport = SmartMessage::Transport::RedisQueueTransport.new(
|
199
|
+
url: 'redis://localhost:6379',
|
200
|
+
consumer_group: 'task_workers'
|
201
|
+
)
|
202
|
+
|
203
|
+
# Start 3 worker threads that share the same queue
|
204
|
+
workers = 3.times.map do |i|
|
205
|
+
Thread.new do
|
206
|
+
worker_transport.where
|
207
|
+
.to('worker_pool')
|
208
|
+
.consumer_group('task_workers')
|
209
|
+
.subscribe do |message_class, message_data|
|
210
|
+
message = JSON.parse(message_data)
|
211
|
+
puts "👷 Worker-#{i+1} received: #{message['task_id']}"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Publish multiple tasks - they'll be distributed among workers
|
217
|
+
5.times do |i|
|
218
|
+
WorkTask.new(
|
219
|
+
task_id: "TASK-#{i+1}",
|
220
|
+
task_type: 'data_processing',
|
221
|
+
estimated_duration: rand(30..120),
|
222
|
+
_sm_header: {
|
223
|
+
from: 'job_scheduler',
|
224
|
+
to: 'worker_pool'
|
225
|
+
}
|
226
|
+
).publish
|
227
|
+
end
|
228
|
+
|
229
|
+
sleep 5
|
230
|
+
workers.each(&:kill)
|
231
|
+
|
232
|
+
#==============================================================================
|
233
|
+
# Example 5: Emergency Alert System with Broadcast
|
234
|
+
#==============================================================================
|
235
|
+
|
236
|
+
class EmergencyAlert < SmartMessage::Base
|
237
|
+
transport :redis_queue
|
238
|
+
|
239
|
+
property :alert_type, required: true
|
240
|
+
property :message, required: true
|
241
|
+
property :severity, default: 'medium'
|
242
|
+
property :affected_areas, default: []
|
243
|
+
|
244
|
+
def process
|
245
|
+
puts "🚨 EMERGENCY ALERT [#{severity}]: #{alert_type} - #{message}"
|
246
|
+
if affected_areas.any?
|
247
|
+
puts "📍 Affected areas: #{affected_areas.join(', ')}"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
puts "\n=== Example 5: Emergency Alert System ==="
|
253
|
+
|
254
|
+
# Set up alert transport
|
255
|
+
alert_transport = SmartMessage::Transport::RedisQueueTransport.new(
|
256
|
+
url: 'redis://localhost:6379',
|
257
|
+
consumer_group: 'emergency_responders'
|
258
|
+
)
|
259
|
+
|
260
|
+
# Emergency services subscribe to alerts
|
261
|
+
alert_transport.subscribe_to_alerts do |message_class, message_data|
|
262
|
+
message = JSON.parse(message_data)
|
263
|
+
puts "🚒 Fire Department received: #{message['alert_type']}"
|
264
|
+
end
|
265
|
+
|
266
|
+
alert_transport.where
|
267
|
+
.from('security_service')
|
268
|
+
.subscribe do |message_class, message_data|
|
269
|
+
message = JSON.parse(message_data)
|
270
|
+
puts "👮 Police Department received security alert: #{message['alert_type']}"
|
271
|
+
end
|
272
|
+
|
273
|
+
alert_transport.subscribe_to_broadcasts do |message_class, message_data|
|
274
|
+
message = JSON.parse(message_data)
|
275
|
+
puts "🏥 Hospital received broadcast: #{message['alert_type']}"
|
276
|
+
end
|
277
|
+
|
278
|
+
# Publish different types of emergency alerts
|
279
|
+
EmergencyAlert.new(
|
280
|
+
alert_type: 'FIRE',
|
281
|
+
message: 'Building fire reported at Main Street complex',
|
282
|
+
severity: 'high',
|
283
|
+
affected_areas: ['Downtown', 'Main Street'],
|
284
|
+
_sm_header: {
|
285
|
+
from: 'fire_detection_system',
|
286
|
+
to: 'fire_department'
|
287
|
+
}
|
288
|
+
).publish
|
289
|
+
|
290
|
+
EmergencyAlert.new(
|
291
|
+
alert_type: 'SECURITY_BREACH',
|
292
|
+
message: 'Unauthorized access detected in server room',
|
293
|
+
severity: 'critical',
|
294
|
+
_sm_header: {
|
295
|
+
from: 'security_service',
|
296
|
+
to: 'security_team'
|
297
|
+
}
|
298
|
+
).publish
|
299
|
+
|
300
|
+
EmergencyAlert.new(
|
301
|
+
alert_type: 'WEATHER_WARNING',
|
302
|
+
message: 'Severe thunderstorm approaching, take shelter',
|
303
|
+
severity: 'high',
|
304
|
+
_sm_header: {
|
305
|
+
from: 'weather_service',
|
306
|
+
to: 'broadcast'
|
307
|
+
}
|
308
|
+
).publish
|
309
|
+
|
310
|
+
sleep 3
|
311
|
+
|
312
|
+
#==============================================================================
|
313
|
+
# Example 6: Microservice Communication Pattern
|
314
|
+
#==============================================================================
|
315
|
+
|
316
|
+
class ServiceRequest < SmartMessage::Base
|
317
|
+
transport :redis_queue
|
318
|
+
|
319
|
+
property :request_id, required: true
|
320
|
+
property :service_name, required: true
|
321
|
+
property :action, required: true
|
322
|
+
property :payload, default: {}
|
323
|
+
|
324
|
+
def process
|
325
|
+
puts "🔧 #{service_name.upcase} processing #{action}: #{request_id}"
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
class ServiceResponse < SmartMessage::Base
|
330
|
+
transport :redis_queue
|
331
|
+
|
332
|
+
property :request_id, required: true
|
333
|
+
property :service_name, required: true
|
334
|
+
property :status, required: true
|
335
|
+
property :result, default: {}
|
336
|
+
|
337
|
+
def process
|
338
|
+
puts "✉️ Response from #{service_name}: #{status} for #{request_id}"
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
puts "\n=== Example 6: Microservice Communication ==="
|
343
|
+
|
344
|
+
# Set up service transport
|
345
|
+
service_transport = SmartMessage::Transport::RedisQueueTransport.new(
|
346
|
+
url: 'redis://localhost:6379',
|
347
|
+
consumer_group: 'microservices'
|
348
|
+
)
|
349
|
+
|
350
|
+
# Services subscribe to their specific requests
|
351
|
+
service_transport.where
|
352
|
+
.to('user_service')
|
353
|
+
.subscribe do |message_class, message_data|
|
354
|
+
request = JSON.parse(message_data)
|
355
|
+
puts "👤 User Service handling: #{request['action']} (#{request['request_id']})"
|
356
|
+
|
357
|
+
# Send response back
|
358
|
+
ServiceResponse.new(
|
359
|
+
request_id: request['request_id'],
|
360
|
+
service_name: 'user_service',
|
361
|
+
status: 'completed',
|
362
|
+
result: { user_data: 'retrieved' },
|
363
|
+
_sm_header: {
|
364
|
+
from: 'user_service',
|
365
|
+
to: 'api_gateway'
|
366
|
+
}
|
367
|
+
).publish
|
368
|
+
end
|
369
|
+
|
370
|
+
service_transport.where
|
371
|
+
.to('payment_service')
|
372
|
+
.subscribe do |message_class, message_data|
|
373
|
+
request = JSON.parse(message_data)
|
374
|
+
puts "💳 Payment Service handling: #{request['action']} (#{request['request_id']})"
|
375
|
+
|
376
|
+
ServiceResponse.new(
|
377
|
+
request_id: request['request_id'],
|
378
|
+
service_name: 'payment_service',
|
379
|
+
status: 'completed',
|
380
|
+
result: { transaction_id: 'TXN-123' },
|
381
|
+
_sm_header: {
|
382
|
+
from: 'payment_service',
|
383
|
+
to: 'api_gateway'
|
384
|
+
}
|
385
|
+
).publish
|
386
|
+
end
|
387
|
+
|
388
|
+
# API Gateway subscribes to responses
|
389
|
+
service_transport.where
|
390
|
+
.to('api_gateway')
|
391
|
+
.subscribe do |message_class, message_data|
|
392
|
+
response = JSON.parse(message_data)
|
393
|
+
puts "🌐 API Gateway received response: #{response['status']} from #{response['service_name']}"
|
394
|
+
end
|
395
|
+
|
396
|
+
# Simulate API requests
|
397
|
+
ServiceRequest.new(
|
398
|
+
request_id: 'REQ-001',
|
399
|
+
service_name: 'user_service',
|
400
|
+
action: 'get_user_profile',
|
401
|
+
payload: { user_id: 12345 },
|
402
|
+
_sm_header: {
|
403
|
+
from: 'api_gateway',
|
404
|
+
to: 'user_service'
|
405
|
+
}
|
406
|
+
).publish
|
407
|
+
|
408
|
+
ServiceRequest.new(
|
409
|
+
request_id: 'REQ-002',
|
410
|
+
service_name: 'payment_service',
|
411
|
+
action: 'process_payment',
|
412
|
+
payload: { amount: 99.99, card_token: 'tok_123' },
|
413
|
+
_sm_header: {
|
414
|
+
from: 'api_gateway',
|
415
|
+
to: 'payment_service'
|
416
|
+
}
|
417
|
+
).publish
|
418
|
+
|
419
|
+
sleep 4
|
420
|
+
|
421
|
+
#==============================================================================
|
422
|
+
# Example 7: Queue Management and Monitoring
|
423
|
+
#==============================================================================
|
424
|
+
|
425
|
+
puts "\n=== Example 7: Queue Management ==="
|
426
|
+
|
427
|
+
# Create transport for management operations
|
428
|
+
mgmt_transport = SmartMessage::Transport::RedisQueueTransport.new(
|
429
|
+
url: 'redis://localhost:6379',
|
430
|
+
consumer_group: 'management'
|
431
|
+
)
|
432
|
+
|
433
|
+
# Check queue statistics
|
434
|
+
puts "📊 Queue Statistics:"
|
435
|
+
stats = mgmt_transport.queue_stats
|
436
|
+
stats.each do |queue_name, info|
|
437
|
+
puts " #{queue_name}: #{info[:length]} messages, pattern: #{info[:pattern]}"
|
438
|
+
end
|
439
|
+
|
440
|
+
# Show routing table
|
441
|
+
puts "\n🗺️ Routing Table:"
|
442
|
+
routing_table = mgmt_transport.routing_table
|
443
|
+
routing_table.each do |pattern, queues|
|
444
|
+
puts " Pattern '#{pattern}' -> #{queues.join(', ')}"
|
445
|
+
end
|
446
|
+
|
447
|
+
# Publish a few more messages to see queue growth
|
448
|
+
3.times do |i|
|
449
|
+
WelcomeMessage.new(
|
450
|
+
user_name: "TestUser#{i+1}",
|
451
|
+
_sm_header: {
|
452
|
+
from: 'test_service',
|
453
|
+
to: 'welcome_service'
|
454
|
+
}
|
455
|
+
).publish
|
456
|
+
end
|
457
|
+
|
458
|
+
puts "\n📊 Updated Queue Statistics:"
|
459
|
+
updated_stats = mgmt_transport.queue_stats
|
460
|
+
updated_stats.each do |queue_name, info|
|
461
|
+
puts " #{queue_name}: #{info[:length]} messages"
|
462
|
+
end
|
463
|
+
|
464
|
+
#==============================================================================
|
465
|
+
# Cleanup
|
466
|
+
#==============================================================================
|
467
|
+
|
468
|
+
puts "\n🧹 Cleaning up..."
|
469
|
+
|
470
|
+
# Close transport connections
|
471
|
+
transport.disconnect if defined?(transport)
|
472
|
+
notification_transport.disconnect if defined?(notification_transport)
|
473
|
+
worker_transport.disconnect if defined?(worker_transport)
|
474
|
+
alert_transport.disconnect if defined?(alert_transport)
|
475
|
+
service_transport.disconnect if defined?(service_transport)
|
476
|
+
mgmt_transport.disconnect if defined?(mgmt_transport)
|
477
|
+
|
478
|
+
puts "✅ Redis Queue Transport examples completed!"
|
479
|
+
|
480
|
+
#==============================================================================
|
481
|
+
# Additional Usage Patterns
|
482
|
+
#==============================================================================
|
483
|
+
|
484
|
+
puts "\n📋 Additional Usage Patterns:\n"
|
485
|
+
|
486
|
+
puts <<~USAGE
|
487
|
+
# Pattern matching examples:
|
488
|
+
transport.subscribe_pattern("#.*.my_service") # All messages TO my_service
|
489
|
+
transport.subscribe_pattern("#.admin.*") # All messages FROM admin
|
490
|
+
transport.subscribe_pattern("order.#.*.*") # All order messages
|
491
|
+
transport.subscribe_pattern("emergency.#.*.broadcast") # Emergency broadcasts
|
492
|
+
|
493
|
+
# Fluent API examples:
|
494
|
+
transport.where.from('api').to('service').subscribe # Specific routing
|
495
|
+
transport.where.type('AlertMessage').subscribe # Message type filtering
|
496
|
+
transport.where.consumer_group('workers').subscribe # Load balancing
|
497
|
+
|
498
|
+
# Convenience methods:
|
499
|
+
transport.subscribe_to_recipient('my_service') # Messages for me
|
500
|
+
transport.subscribe_from_sender('trusted_service') # Messages from trusted source
|
501
|
+
transport.subscribe_to_broadcasts # Broadcast messages
|
502
|
+
transport.subscribe_to_alerts # Emergency alerts
|
503
|
+
|
504
|
+
# Queue management:
|
505
|
+
transport.queue_stats # Monitor queue lengths
|
506
|
+
transport.routing_table # View routing patterns
|
507
|
+
transport.clear_queue('queue_name') # Clear specific queue
|
508
|
+
USAGE
|