smart_message 0.0.9 → 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 +53 -0
- data/Gemfile.lock +35 -4
- data/README.md +265 -69
- 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} +129 -119
- 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/reference/message-deduplication.md +489 -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/memory/01_message_deduplication_demo.rb +209 -0
- 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 +2 -2
- data/lib/smart_message/configuration.rb +1 -1
- data/lib/smart_message/ddq/base.rb +71 -0
- data/lib/smart_message/ddq/memory.rb +109 -0
- data/lib/smart_message/ddq/redis.rb +168 -0
- data/lib/smart_message/ddq.rb +31 -0
- data/lib/smart_message/deduplication.rb +174 -0
- data/lib/smart_message/dispatcher.rb +175 -18
- 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/subscription.rb +10 -7
- 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 +175 -42
- 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,209 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# examples/10_message_deduplication.rb
|
3
|
+
|
4
|
+
require_relative '../../lib/smart_message'
|
5
|
+
|
6
|
+
# Example demonstrating message deduplication with DDQ (Deduplication Queue)
|
7
|
+
|
8
|
+
# Message class with deduplication enabled
|
9
|
+
class OrderMessage < SmartMessage::Base
|
10
|
+
version 1
|
11
|
+
property :order_id, required: true
|
12
|
+
property :amount, required: true
|
13
|
+
|
14
|
+
from "order-service"
|
15
|
+
|
16
|
+
# Configure deduplication
|
17
|
+
ddq_size 100 # Keep track of last 100 message UUIDs
|
18
|
+
ddq_storage :memory # Use memory storage (could be :redis)
|
19
|
+
enable_deduplication! # Enable deduplication for this message class
|
20
|
+
|
21
|
+
def self.process(message)
|
22
|
+
puts "✅ Processing order: #{message.order_id} for $#{message.amount}"
|
23
|
+
@@processed_orders ||= []
|
24
|
+
@@processed_orders << message.order_id
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.processed_orders
|
28
|
+
@@processed_orders || []
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.clear_processed
|
32
|
+
@@processed_orders = []
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Regular message class without deduplication
|
37
|
+
class NotificationMessage < SmartMessage::Base
|
38
|
+
version 1
|
39
|
+
property :message, required: true
|
40
|
+
property :recipient, required: true
|
41
|
+
|
42
|
+
from "notification-service"
|
43
|
+
|
44
|
+
def self.process(message)
|
45
|
+
puts "📧 Sending: '#{message.message}' to #{message.recipient}"
|
46
|
+
@@sent_notifications ||= []
|
47
|
+
@@sent_notifications << { message: message.message, recipient: message.recipient }
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.sent_notifications
|
51
|
+
@@sent_notifications || []
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.clear_processed
|
55
|
+
@@sent_notifications = []
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def demonstrate_deduplication
|
60
|
+
puts "=== SmartMessage Deduplication Demo ==="
|
61
|
+
puts
|
62
|
+
|
63
|
+
# Setup transport and subscriptions
|
64
|
+
transport = SmartMessage::Transport::MemoryTransport.new
|
65
|
+
|
66
|
+
OrderMessage.transport(transport)
|
67
|
+
OrderMessage.serializer(SmartMessage::Serializer::Json.new)
|
68
|
+
OrderMessage.subscribe('OrderMessage.process')
|
69
|
+
|
70
|
+
NotificationMessage.transport(transport)
|
71
|
+
NotificationMessage.serializer(SmartMessage::Serializer::Json.new)
|
72
|
+
NotificationMessage.subscribe('NotificationMessage.process')
|
73
|
+
|
74
|
+
# Clear any previous state
|
75
|
+
OrderMessage.clear_processed
|
76
|
+
NotificationMessage.clear_processed
|
77
|
+
OrderMessage.clear_ddq!
|
78
|
+
|
79
|
+
puts "📊 DDQ Configuration:"
|
80
|
+
config = OrderMessage.ddq_config
|
81
|
+
puts " - Enabled: #{config[:enabled]}"
|
82
|
+
puts " - Size: #{config[:size]}"
|
83
|
+
puts " - Storage: #{config[:storage]}"
|
84
|
+
puts
|
85
|
+
|
86
|
+
# Create a specific UUID for testing duplicates
|
87
|
+
uuid = SecureRandom.uuid
|
88
|
+
puts "🔍 Testing with UUID: #{uuid}"
|
89
|
+
puts
|
90
|
+
|
91
|
+
# Test 1: OrderMessage with deduplication
|
92
|
+
puts "--- Test 1: OrderMessage (with deduplication) ---"
|
93
|
+
|
94
|
+
# Create header with specific UUID
|
95
|
+
header = SmartMessage::Header.new(
|
96
|
+
uuid: uuid,
|
97
|
+
message_class: "OrderMessage",
|
98
|
+
published_at: Time.now,
|
99
|
+
publisher_pid: Process.pid,
|
100
|
+
version: 1,
|
101
|
+
from: "order-service"
|
102
|
+
)
|
103
|
+
|
104
|
+
# First message
|
105
|
+
order1 = OrderMessage.new(
|
106
|
+
_sm_header: header,
|
107
|
+
_sm_payload: { order_id: "ORD-001", amount: 99.99 }
|
108
|
+
)
|
109
|
+
|
110
|
+
puts "Publishing first order message..."
|
111
|
+
order1.publish
|
112
|
+
sleep 0.1 # Allow processing
|
113
|
+
|
114
|
+
# Second message with SAME UUID (should be deduplicated)
|
115
|
+
order2 = OrderMessage.new(
|
116
|
+
_sm_header: header,
|
117
|
+
_sm_payload: { order_id: "ORD-002", amount: 149.99 }
|
118
|
+
)
|
119
|
+
|
120
|
+
puts "Publishing duplicate order message (same UUID)..."
|
121
|
+
order2.publish
|
122
|
+
sleep 0.1 # Allow processing
|
123
|
+
|
124
|
+
puts "📈 Results:"
|
125
|
+
puts " - Processed orders: #{OrderMessage.processed_orders.length}"
|
126
|
+
puts " - Orders: #{OrderMessage.processed_orders}"
|
127
|
+
puts
|
128
|
+
|
129
|
+
# Test 2: NotificationMessage without deduplication
|
130
|
+
puts "--- Test 2: NotificationMessage (no deduplication) ---"
|
131
|
+
|
132
|
+
# Create header with same UUID
|
133
|
+
notification_header = SmartMessage::Header.new(
|
134
|
+
uuid: uuid, # Same UUID as orders!
|
135
|
+
message_class: "NotificationMessage",
|
136
|
+
published_at: Time.now,
|
137
|
+
publisher_pid: Process.pid,
|
138
|
+
version: 1,
|
139
|
+
from: "notification-service"
|
140
|
+
)
|
141
|
+
|
142
|
+
# First notification
|
143
|
+
notif1 = NotificationMessage.new(
|
144
|
+
_sm_header: notification_header,
|
145
|
+
_sm_payload: { message: "Order confirmed", recipient: "customer@example.com" }
|
146
|
+
)
|
147
|
+
|
148
|
+
puts "Publishing first notification..."
|
149
|
+
notif1.publish
|
150
|
+
sleep 0.1
|
151
|
+
|
152
|
+
# Second notification with same UUID (should NOT be deduplicated)
|
153
|
+
notif2 = NotificationMessage.new(
|
154
|
+
_sm_header: notification_header,
|
155
|
+
_sm_payload: { message: "Order shipped", recipient: "customer@example.com" }
|
156
|
+
)
|
157
|
+
|
158
|
+
puts "Publishing duplicate notification (same UUID)..."
|
159
|
+
notif2.publish
|
160
|
+
sleep 0.1
|
161
|
+
|
162
|
+
puts "📈 Results:"
|
163
|
+
puts " - Sent notifications: #{NotificationMessage.sent_notifications.length}"
|
164
|
+
puts " - Notifications: #{NotificationMessage.sent_notifications}"
|
165
|
+
puts
|
166
|
+
|
167
|
+
# Show DDQ statistics
|
168
|
+
puts "📊 DDQ Statistics:"
|
169
|
+
stats = OrderMessage.ddq_stats
|
170
|
+
if stats[:enabled]
|
171
|
+
puts " - Current count: #{stats[:current_count]}"
|
172
|
+
puts " - Utilization: #{stats[:utilization]}%"
|
173
|
+
puts " - Storage type: #{stats[:storage_type]}"
|
174
|
+
else
|
175
|
+
puts " - DDQ not enabled"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def demonstrate_memory_efficiency
|
180
|
+
puts
|
181
|
+
puts "=== Memory Usage Demonstration ==="
|
182
|
+
puts
|
183
|
+
|
184
|
+
# Show memory usage for different DDQ sizes
|
185
|
+
test_sizes = [10, 100, 1000]
|
186
|
+
|
187
|
+
test_sizes.each do |size|
|
188
|
+
memory_usage = size * 48 # Approximate bytes per UUID
|
189
|
+
puts "DDQ size #{size}: ~#{memory_usage} bytes (~#{(memory_usage / 1024.0).round(1)} KB)"
|
190
|
+
end
|
191
|
+
|
192
|
+
puts
|
193
|
+
puts "💡 Memory is very reasonable - even 1000 entries uses less than 50KB!"
|
194
|
+
end
|
195
|
+
|
196
|
+
if __FILE__ == $0
|
197
|
+
demonstrate_deduplication
|
198
|
+
demonstrate_memory_efficiency
|
199
|
+
|
200
|
+
puts
|
201
|
+
puts "✨ Key Benefits:"
|
202
|
+
puts " - O(1) duplicate detection"
|
203
|
+
puts " - Configurable queue size"
|
204
|
+
puts " - Memory or Redis storage"
|
205
|
+
puts " - Per-message-class configuration"
|
206
|
+
puts " - Automatic integration with dispatcher"
|
207
|
+
puts
|
208
|
+
puts "🚀 Ready for production multi-transport scenarios!"
|
209
|
+
end
|
@@ -11,7 +11,7 @@
|
|
11
11
|
# - Administrative functions
|
12
12
|
# - Monitoring and statistics
|
13
13
|
|
14
|
-
require_relative '
|
14
|
+
require_relative '../../lib/smart_message'
|
15
15
|
require 'json'
|
16
16
|
require 'fileutils'
|
17
17
|
|
@@ -45,7 +45,7 @@ class PaymentMessage < SmartMessage::Base
|
|
45
45
|
|
46
46
|
config do
|
47
47
|
transport SmartMessage::Transport.create(:memory)
|
48
|
-
serializer SmartMessage::Serializer::
|
48
|
+
serializer SmartMessage::Serializer::Json.new
|
49
49
|
end
|
50
50
|
|
51
51
|
def self.process(wrapper)
|
@@ -68,7 +68,7 @@ class OrderMessage < SmartMessage::Base
|
|
68
68
|
|
69
69
|
config do
|
70
70
|
transport SmartMessage::Transport.create(:memory)
|
71
|
-
serializer SmartMessage::Serializer::
|
71
|
+
serializer SmartMessage::Serializer::Json.new
|
72
72
|
end
|
73
73
|
|
74
74
|
def self.process(wrapper)
|
@@ -90,7 +90,7 @@ class NotificationMessage < SmartMessage::Base
|
|
90
90
|
|
91
91
|
config do
|
92
92
|
transport SmartMessage::Transport.create(:memory)
|
93
|
-
serializer SmartMessage::Serializer::
|
93
|
+
serializer SmartMessage::Serializer::Json.new
|
94
94
|
end
|
95
95
|
|
96
96
|
def self.process(wrapper)
|
@@ -193,12 +193,8 @@ rescue => e
|
|
193
193
|
puts "❌ Validation failed: #{e.message}"
|
194
194
|
|
195
195
|
# Manually add to DLQ
|
196
|
-
wrapper = SmartMessage::Wrapper::Base.new(
|
197
|
-
header: payment._sm_header,
|
198
|
-
payload: payment.encode
|
199
|
-
)
|
200
196
|
dlq.enqueue(
|
201
|
-
|
197
|
+
payment,
|
202
198
|
error: e.message,
|
203
199
|
transport: "ValidationLayer",
|
204
200
|
retry_count: 0
|
@@ -236,12 +232,8 @@ rescue => e
|
|
236
232
|
puts "❌ Publish failed: #{e.message}"
|
237
233
|
|
238
234
|
# Circuit breaker would normally handle this, but we'll add manually for demo
|
239
|
-
wrapper = SmartMessage::Wrapper::Base.new(
|
240
|
-
header: payment._sm_header,
|
241
|
-
payload: payment.encode
|
242
|
-
)
|
243
235
|
dlq.enqueue(
|
244
|
-
|
236
|
+
payment,
|
245
237
|
error: e.message,
|
246
238
|
transport: failing_transport.class.name,
|
247
239
|
retry_count: 1
|
@@ -263,12 +255,8 @@ order = OrderMessage.new(
|
|
263
255
|
total: 99.99
|
264
256
|
)
|
265
257
|
|
266
|
-
wrapper = SmartMessage::Wrapper::Base.new(
|
267
|
-
header: order._sm_header,
|
268
|
-
payload: order.encode
|
269
|
-
)
|
270
258
|
dlq.enqueue(
|
271
|
-
|
259
|
+
order,
|
272
260
|
error: "Gateway timeout after 30 seconds",
|
273
261
|
transport: "Redis",
|
274
262
|
retry_count: 3
|
@@ -282,12 +270,8 @@ notification = NotificationMessage.new(
|
|
282
270
|
channel: "sms"
|
283
271
|
)
|
284
272
|
|
285
|
-
wrapper = SmartMessage::Wrapper::Base.new(
|
286
|
-
header: notification._sm_header,
|
287
|
-
payload: notification.encode
|
288
|
-
)
|
289
273
|
dlq.enqueue(
|
290
|
-
|
274
|
+
notification,
|
291
275
|
error: "Rate limit exceeded: 429 Too Many Requests",
|
292
276
|
transport: "SMSGateway",
|
293
277
|
retry_count: 1
|
@@ -301,12 +285,8 @@ payment3 = PaymentMessage.new(
|
|
301
285
|
customer_id: "CUST-789"
|
302
286
|
)
|
303
287
|
|
304
|
-
wrapper = SmartMessage::Wrapper::Base.new(
|
305
|
-
header: payment3._sm_header,
|
306
|
-
payload: payment3.encode
|
307
|
-
)
|
308
288
|
dlq.enqueue(
|
309
|
-
|
289
|
+
payment3,
|
310
290
|
error: "Invalid merchant credentials",
|
311
291
|
transport: "StripeGateway",
|
312
292
|
retry_count: 0
|
@@ -461,17 +441,10 @@ temp_messages = []
|
|
461
441
|
puts " #{i + 1}. #{msg[:header][:message_class]} - #{msg[:timestamp]}"
|
462
442
|
end
|
463
443
|
|
464
|
-
#
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
header: header,
|
469
|
-
payload: msg[:payload]
|
470
|
-
)
|
471
|
-
dlq.enqueue(wrapper,
|
472
|
-
error: msg[:error],
|
473
|
-
retry_count: msg[:retry_count])
|
474
|
-
end
|
444
|
+
# Note: For demo purposes, we dequeued messages to show FIFO order.
|
445
|
+
# In a real application, you would typically replay them instead of manually re-enqueuing.
|
446
|
+
puts "\n📝 Messages were dequeued to demonstrate FIFO order."
|
447
|
+
puts " In production, use dlq.replay_batch() to properly restore and replay messages."
|
475
448
|
|
476
449
|
# ==============================================================================
|
477
450
|
|
@@ -6,7 +6,7 @@
|
|
6
6
|
# This example demonstrates point-to-point messaging between an OrderService
|
7
7
|
# and a PaymentService. Each order gets processed by exactly one payment processor.
|
8
8
|
|
9
|
-
require_relative '
|
9
|
+
require_relative '../../lib/smart_message'
|
10
10
|
|
11
11
|
puts "=== SmartMessage Example: Point-to-Point Order Processing ==="
|
12
12
|
puts
|
@@ -6,7 +6,7 @@
|
|
6
6
|
# This example demonstrates publish-subscribe messaging where one event publisher
|
7
7
|
# sends notifications to multiple subscribers (email service, SMS service, audit logger).
|
8
8
|
|
9
|
-
require_relative '
|
9
|
+
require_relative '../../lib/smart_message'
|
10
10
|
|
11
11
|
puts "=== SmartMessage Example: Publish-Subscribe Event Notifications ==="
|
12
12
|
puts
|
@@ -32,7 +32,7 @@ class UserEventMessage < SmartMessage::Base
|
|
32
32
|
|
33
33
|
config do
|
34
34
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
35
|
-
serializer SmartMessage::Serializer::
|
35
|
+
serializer SmartMessage::Serializer::Json.new
|
36
36
|
end
|
37
37
|
|
38
38
|
# Default processor - just logs the event
|
@@ -7,7 +7,7 @@
|
|
7
7
|
# can send messages to multiple chat rooms, and other agents receive and respond
|
8
8
|
# to messages based on their interests and capabilities.
|
9
9
|
|
10
|
-
require_relative '
|
10
|
+
require_relative '../../lib/smart_message'
|
11
11
|
|
12
12
|
puts "=== SmartMessage Example: Many-to-Many Distributed Chat ==="
|
13
13
|
puts
|
@@ -37,7 +37,7 @@ class ChatMessage < SmartMessage::Base
|
|
37
37
|
|
38
38
|
config do
|
39
39
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
40
|
-
serializer SmartMessage::Serializer::
|
40
|
+
serializer SmartMessage::Serializer::Json.new
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.process(wrapper)
|
@@ -66,7 +66,7 @@ class BotCommandMessage < SmartMessage::Base
|
|
66
66
|
|
67
67
|
config do
|
68
68
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
69
|
-
serializer SmartMessage::Serializer::
|
69
|
+
serializer SmartMessage::Serializer::Json.new
|
70
70
|
end
|
71
71
|
|
72
72
|
def self.process(wrapper)
|
@@ -95,7 +95,7 @@ class SystemNotificationMessage < SmartMessage::Base
|
|
95
95
|
|
96
96
|
config do
|
97
97
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
98
|
-
serializer SmartMessage::Serializer::
|
98
|
+
serializer SmartMessage::Serializer::Json.new
|
99
99
|
end
|
100
100
|
|
101
101
|
def self.process(wrapper)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# show_me.rb - Demonstrates the pretty_print method on SmartMessage instances
|
3
3
|
|
4
|
-
require_relative '
|
4
|
+
require_relative '../../lib/smart_message'
|
5
5
|
|
6
6
|
# Define a sample order message
|
7
7
|
class OrderMessage < SmartMessage::Base
|
@@ -7,7 +7,7 @@
|
|
7
7
|
# in SmartMessage, showing different ways to subscribe to messages beyond
|
8
8
|
# the traditional self.process method.
|
9
9
|
|
10
|
-
require_relative '
|
10
|
+
require_relative '../../lib/smart_message'
|
11
11
|
|
12
12
|
puts "=== SmartMessage Proc and Block Handler Example ==="
|
13
13
|
puts
|
@@ -29,7 +29,7 @@ class NotificationMessage < SmartMessage::Base
|
|
29
29
|
|
30
30
|
config do
|
31
31
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
32
|
-
serializer SmartMessage::Serializer::
|
32
|
+
serializer SmartMessage::Serializer::Json.new
|
33
33
|
end
|
34
34
|
|
35
35
|
# Default handler
|
@@ -44,7 +44,7 @@
|
|
44
44
|
# 2. Configure it at the class level: logger SmartMessage::Logger::RailsLogger.new
|
45
45
|
# 3. All messages will be logged to your Rails application logs
|
46
46
|
|
47
|
-
require_relative '
|
47
|
+
require_relative '../../lib/smart_message'
|
48
48
|
require 'logger'
|
49
49
|
require 'json'
|
50
50
|
require 'fileutils'
|
@@ -293,7 +293,7 @@ class OrderProcessingMessage < SmartMessage::Base
|
|
293
293
|
|
294
294
|
config do
|
295
295
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
296
|
-
serializer SmartMessage::Serializer::
|
296
|
+
serializer SmartMessage::Serializer::Json.new
|
297
297
|
|
298
298
|
# Configure multi-logger to demonstrate different logging approaches
|
299
299
|
logger SmartMessage::Logger::MultiLogger.new(
|
@@ -364,7 +364,7 @@ class NotificationMessage < SmartMessage::Base
|
|
364
364
|
|
365
365
|
config do
|
366
366
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
367
|
-
serializer SmartMessage::Serializer::
|
367
|
+
serializer SmartMessage::Serializer::Json.new
|
368
368
|
|
369
369
|
# Use only file logger for notifications
|
370
370
|
logger SmartMessage::Logger::FileLogger.new('logs/notifications.log', level: Logger::WARN)
|
@@ -401,7 +401,7 @@ class StandardLoggerMessage < SmartMessage::Base
|
|
401
401
|
|
402
402
|
config do
|
403
403
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
404
|
-
serializer SmartMessage::Serializer::
|
404
|
+
serializer SmartMessage::Serializer::Json.new
|
405
405
|
|
406
406
|
# Example 1: Using Ruby's standard Logger directly
|
407
407
|
# Create a standard Ruby logger that logs to STDOUT
|
@@ -439,7 +439,7 @@ class DefaultLoggerMessage < SmartMessage::Base
|
|
439
439
|
|
440
440
|
config do
|
441
441
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
442
|
-
serializer SmartMessage::Serializer::
|
442
|
+
serializer SmartMessage::Serializer::Json.new
|
443
443
|
|
444
444
|
# Use the built-in default logger - simplest option!
|
445
445
|
logger SmartMessage::Logger::Default.new
|
@@ -466,16 +466,19 @@ class PriorityOrderService
|
|
466
466
|
end
|
467
467
|
|
468
468
|
def process_priority_order(order_data)
|
469
|
-
#
|
470
|
-
|
469
|
+
# Use class-level logger override for this specific processing
|
470
|
+
original_logger = OrderProcessingMessage.logger
|
471
|
+
OrderProcessingMessage.logger(@priority_logger)
|
471
472
|
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
473
|
+
begin
|
474
|
+
message = OrderProcessingMessage.new(**order_data, from: 'PriorityOrderService')
|
475
|
+
puts "⚡ Processing priority order with dedicated logger"
|
476
|
+
message.publish
|
477
|
+
message
|
478
|
+
ensure
|
479
|
+
# Restore original logger
|
480
|
+
OrderProcessingMessage.logger(original_logger)
|
481
|
+
end
|
479
482
|
end
|
480
483
|
end
|
481
484
|
|
@@ -11,7 +11,7 @@
|
|
11
11
|
# These scenarios help developers understand SmartMessage's robust error handling
|
12
12
|
# and how to build resilient message-based systems.
|
13
13
|
|
14
|
-
require_relative '
|
14
|
+
require_relative '../../lib/smart_message'
|
15
15
|
|
16
16
|
puts "=== SmartMessage Example: Error Handling Scenarios ==="
|
17
17
|
puts
|
@@ -50,7 +50,7 @@ class UserRegistrationMessage < SmartMessage::Base
|
|
50
50
|
|
51
51
|
config do
|
52
52
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
53
|
-
serializer SmartMessage::Serializer::
|
53
|
+
serializer SmartMessage::Serializer::Json.new
|
54
54
|
end
|
55
55
|
|
56
56
|
def self.process(wrapper)
|
@@ -99,7 +99,7 @@ class UserRegistrationMessageV2 < SmartMessage::Base
|
|
99
99
|
|
100
100
|
config do
|
101
101
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
102
|
-
serializer SmartMessage::Serializer::
|
102
|
+
serializer SmartMessage::Serializer::Json.new
|
103
103
|
end
|
104
104
|
|
105
105
|
def self.process(wrapper)
|
@@ -121,7 +121,7 @@ class MultiRequiredMessage < SmartMessage::Base
|
|
121
121
|
|
122
122
|
config do
|
123
123
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
124
|
-
serializer SmartMessage::Serializer::
|
124
|
+
serializer SmartMessage::Serializer::Json.new
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
@@ -8,14 +8,14 @@
|
|
8
8
|
# - Instance-level addressing overrides
|
9
9
|
# - Gateway patterns
|
10
10
|
|
11
|
-
require_relative '
|
11
|
+
require_relative '../../lib/smart_message'
|
12
12
|
|
13
13
|
puts "🎯 SmartMessage Entity Addressing Demo"
|
14
14
|
puts "=" * 50
|
15
15
|
|
16
16
|
# Configure transport for demo
|
17
17
|
transport = SmartMessage::Transport.create(:stdout, loopback: true)
|
18
|
-
serializer = SmartMessage::Serializer::
|
18
|
+
serializer = SmartMessage::Serializer::Json.new
|
19
19
|
|
20
20
|
# =============================================================================
|
21
21
|
# Example 1: Point-to-Point Messaging
|
@@ -40,7 +40,7 @@ class OrderMessage < SmartMessage::Base
|
|
40
40
|
|
41
41
|
config do
|
42
42
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
43
|
-
serializer SmartMessage::Serializer::
|
43
|
+
serializer SmartMessage::Serializer::Json.new
|
44
44
|
end
|
45
45
|
|
46
46
|
def self.process(wrapper)
|
@@ -93,7 +93,7 @@ class SystemAnnouncementMessage < SmartMessage::Base
|
|
93
93
|
|
94
94
|
config do
|
95
95
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
96
|
-
serializer SmartMessage::Serializer::
|
96
|
+
serializer SmartMessage::Serializer::Json.new
|
97
97
|
end
|
98
98
|
|
99
99
|
def self.process(wrapper)
|
@@ -145,7 +145,7 @@ class UserLookupRequest < SmartMessage::Base
|
|
145
145
|
|
146
146
|
config do
|
147
147
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
148
|
-
serializer SmartMessage::Serializer::
|
148
|
+
serializer SmartMessage::Serializer::Json.new
|
149
149
|
end
|
150
150
|
|
151
151
|
def self.process(wrapper)
|
@@ -179,7 +179,7 @@ class UserLookupResponse < SmartMessage::Base
|
|
179
179
|
|
180
180
|
config do
|
181
181
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
182
|
-
serializer SmartMessage::Serializer::
|
182
|
+
serializer SmartMessage::Serializer::Json.new
|
183
183
|
end
|
184
184
|
|
185
185
|
def self.process(wrapper)
|
@@ -251,7 +251,7 @@ class PaymentMessage < SmartMessage::Base
|
|
251
251
|
|
252
252
|
config do
|
253
253
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
254
|
-
serializer SmartMessage::Serializer::
|
254
|
+
serializer SmartMessage::Serializer::Json.new
|
255
255
|
end
|
256
256
|
|
257
257
|
def self.process(wrapper)
|
@@ -326,7 +326,7 @@ class ExternalAPIMessage < SmartMessage::Base
|
|
326
326
|
|
327
327
|
config do
|
328
328
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
329
|
-
serializer SmartMessage::Serializer::
|
329
|
+
serializer SmartMessage::Serializer::Json.new
|
330
330
|
end
|
331
331
|
|
332
332
|
def self.process(wrapper)
|
@@ -9,14 +9,14 @@
|
|
9
9
|
# - Instance-level addressing overrides
|
10
10
|
# - Gateway patterns
|
11
11
|
|
12
|
-
require_relative '
|
12
|
+
require_relative '../../lib/smart_message'
|
13
13
|
|
14
14
|
puts "🎯 SmartMessage Entity Addressing & Filtering Demo"
|
15
15
|
puts "=" * 50
|
16
16
|
|
17
17
|
# Configure transport for demo
|
18
18
|
transport = SmartMessage::Transport.create(:stdout, loopback: true)
|
19
|
-
serializer = SmartMessage::Serializer::
|
19
|
+
serializer = SmartMessage::Serializer::Json.new
|
20
20
|
|
21
21
|
# =============================================================================
|
22
22
|
# Example 1: Entity-Aware Message Filtering
|
@@ -37,7 +37,7 @@ class ServiceMessage < SmartMessage::Base
|
|
37
37
|
|
38
38
|
config do
|
39
39
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
40
|
-
serializer SmartMessage::Serializer::
|
40
|
+
serializer SmartMessage::Serializer::Json.new
|
41
41
|
end
|
42
42
|
|
43
43
|
# Different handlers for different subscription filters
|
@@ -154,7 +154,7 @@ class AlertMessage < SmartMessage::Base
|
|
154
154
|
|
155
155
|
config do
|
156
156
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
157
|
-
serializer SmartMessage::Serializer::
|
157
|
+
serializer SmartMessage::Serializer::Json.new
|
158
158
|
end
|
159
159
|
|
160
160
|
def self.process_critical_or_broadcast(wrapper)
|
@@ -262,7 +262,7 @@ class OrderMessage < SmartMessage::Base
|
|
262
262
|
|
263
263
|
config do
|
264
264
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
265
|
-
serializer SmartMessage::Serializer::
|
265
|
+
serializer SmartMessage::Serializer::Json.new
|
266
266
|
end
|
267
267
|
|
268
268
|
def self.process_high_priority(wrapper)
|
@@ -357,7 +357,7 @@ class ServiceRequest < SmartMessage::Base
|
|
357
357
|
|
358
358
|
config do
|
359
359
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
360
|
-
serializer SmartMessage::Serializer::
|
360
|
+
serializer SmartMessage::Serializer::Json.new
|
361
361
|
end
|
362
362
|
|
363
363
|
def self.process_api_requests(wrapper)
|
data/examples/{09_regex_filtering_microservices.rb → memory/12_regex_filtering_microservices.rb}
RENAMED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# examples/09_regex_filtering_microservices.rb
|
3
3
|
|
4
|
-
require_relative '
|
4
|
+
require_relative '../../lib/smart_message'
|
5
5
|
|
6
6
|
# Example: Advanced Regex Filtering for Microservices Architecture
|
7
7
|
#
|
@@ -31,7 +31,7 @@ class MicroserviceMessage < SmartMessage::Base
|
|
31
31
|
# Configure with STDOUT transport for demo visibility
|
32
32
|
config do
|
33
33
|
transport SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
34
|
-
serializer SmartMessage::Serializer::
|
34
|
+
serializer SmartMessage::Serializer::Json.new
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|