smart_message 0.0.7 → 0.0.9
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/.gitignore +1 -0
- data/.irbrc +24 -0
- data/CHANGELOG.md +143 -0
- data/Gemfile.lock +6 -1
- data/README.md +289 -15
- data/docs/README.md +3 -1
- data/docs/addressing.md +119 -13
- data/docs/architecture.md +68 -0
- data/docs/dead_letter_queue.md +673 -0
- data/docs/dispatcher.md +87 -0
- data/docs/examples.md +59 -1
- data/docs/getting-started.md +8 -1
- data/docs/logging.md +382 -326
- data/docs/message_filtering.md +451 -0
- data/examples/01_point_to_point_orders.rb +54 -53
- data/examples/02_publish_subscribe_events.rb +14 -10
- data/examples/03_many_to_many_chat.rb +16 -8
- data/examples/04_redis_smart_home_iot.rb +20 -10
- data/examples/05_proc_handlers.rb +12 -11
- data/examples/06_custom_logger_example.rb +95 -100
- data/examples/07_error_handling_scenarios.rb +4 -2
- data/examples/08_entity_addressing_basic.rb +18 -6
- data/examples/08_entity_addressing_with_filtering.rb +27 -9
- data/examples/09_dead_letter_queue_demo.rb +559 -0
- data/examples/09_regex_filtering_microservices.rb +407 -0
- data/examples/10_header_block_configuration.rb +263 -0
- data/examples/11_global_configuration_example.rb +219 -0
- data/examples/README.md +102 -0
- data/examples/dead_letters.jsonl +12 -0
- data/examples/performance_metrics/benchmark_results_ractor_20250818_205603.json +135 -0
- data/examples/performance_metrics/benchmark_results_ractor_20250818_205831.json +135 -0
- data/examples/performance_metrics/benchmark_results_test_20250818_204942.json +130 -0
- data/examples/performance_metrics/benchmark_results_threadpool_20250818_204942.json +130 -0
- data/examples/performance_metrics/benchmark_results_threadpool_20250818_204959.json +130 -0
- data/examples/performance_metrics/benchmark_results_threadpool_20250818_205044.json +130 -0
- data/examples/performance_metrics/benchmark_results_threadpool_20250818_205109.json +130 -0
- data/examples/performance_metrics/benchmark_results_threadpool_20250818_205252.json +130 -0
- data/examples/performance_metrics/benchmark_results_unknown_20250819_172852.json +130 -0
- data/examples/performance_metrics/compare_benchmarks.rb +519 -0
- data/examples/performance_metrics/dead_letters.jsonl +3100 -0
- data/examples/performance_metrics/performance_benchmark.rb +344 -0
- data/examples/show_logger.rb +367 -0
- data/examples/show_me.rb +145 -0
- data/examples/temp.txt +94 -0
- data/examples/tmux_chat/bot_agent.rb +4 -2
- data/examples/tmux_chat/human_agent.rb +4 -2
- data/examples/tmux_chat/room_monitor.rb +4 -2
- data/examples/tmux_chat/shared_chat_system.rb +6 -3
- data/lib/smart_message/addressing.rb +259 -0
- data/lib/smart_message/base.rb +121 -599
- data/lib/smart_message/circuit_breaker.rb +23 -6
- data/lib/smart_message/configuration.rb +199 -0
- data/lib/smart_message/dead_letter_queue.rb +361 -0
- data/lib/smart_message/dispatcher.rb +90 -49
- data/lib/smart_message/header.rb +5 -0
- data/lib/smart_message/logger/base.rb +21 -1
- data/lib/smart_message/logger/default.rb +88 -138
- data/lib/smart_message/logger/lumberjack.rb +324 -0
- data/lib/smart_message/logger/null.rb +81 -0
- data/lib/smart_message/logger.rb +17 -9
- data/lib/smart_message/messaging.rb +100 -0
- data/lib/smart_message/plugins.rb +132 -0
- data/lib/smart_message/serializer/base.rb +25 -8
- data/lib/smart_message/serializer/json.rb +5 -4
- data/lib/smart_message/subscription.rb +193 -0
- data/lib/smart_message/transport/base.rb +84 -53
- data/lib/smart_message/transport/memory_transport.rb +7 -5
- data/lib/smart_message/transport/redis_transport.rb +15 -45
- data/lib/smart_message/transport/stdout_transport.rb +18 -8
- data/lib/smart_message/transport.rb +1 -34
- data/lib/smart_message/utilities.rb +142 -0
- data/lib/smart_message/version.rb +1 -1
- data/lib/smart_message/versioning.rb +85 -0
- data/lib/smart_message/wrapper.rb.bak +132 -0
- data/lib/smart_message.rb +74 -27
- data/smart_message.gemspec +3 -0
- metadata +77 -3
- data/lib/smart_message/serializer.rb +0 -10
- data/lib/smart_message/wrapper.rb +0 -43
@@ -0,0 +1,219 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# examples/11_global_configuration_example.rb
|
3
|
+
#
|
4
|
+
# Global Configuration System Example
|
5
|
+
#
|
6
|
+
# This example demonstrates how to use SmartMessage's global configuration
|
7
|
+
# system to set default logger, transport, and serializer for all message
|
8
|
+
# classes in your application.
|
9
|
+
|
10
|
+
require_relative '../lib/smart_message'
|
11
|
+
|
12
|
+
puts "=== SmartMessage Global Configuration Example ==="
|
13
|
+
puts
|
14
|
+
|
15
|
+
# Example 1: Default behavior (no configuration) - NO LOGGING
|
16
|
+
puts "1. Default Framework Behavior (NO LOGGING):"
|
17
|
+
puts " Default Logger: #{SmartMessage::Logger.default.class}"
|
18
|
+
puts " Default Transport: #{SmartMessage::Transport.default.class}"
|
19
|
+
puts " Default Serializer: #{SmartMessage::Serializer.default.class}"
|
20
|
+
puts " Note: No logging unless explicitly configured!"
|
21
|
+
puts
|
22
|
+
|
23
|
+
# Example 2: Configure logging with string path
|
24
|
+
puts "2. Configuring Logging with String Path:"
|
25
|
+
SmartMessage.configure do |config|
|
26
|
+
config.logger = "log/my_application.log" # String = Lumberjack logger with this path
|
27
|
+
config.transport = SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
28
|
+
config.serializer = SmartMessage::Serializer::Json.new
|
29
|
+
end
|
30
|
+
|
31
|
+
puts " Configured Logger: #{SmartMessage::Logger.default.class}"
|
32
|
+
puts " Log File: #{SmartMessage::Logger.default.log_file rescue 'N/A'}"
|
33
|
+
puts " Configured Transport: #{SmartMessage::Transport.default.class}"
|
34
|
+
puts " Configured Serializer: #{SmartMessage::Serializer.default.class}"
|
35
|
+
puts
|
36
|
+
|
37
|
+
# Reset for next example
|
38
|
+
SmartMessage.reset_configuration!
|
39
|
+
|
40
|
+
# Example 3: Configure with :default symbol (framework defaults)
|
41
|
+
puts "3. Configuring with :default Symbol:"
|
42
|
+
SmartMessage.configure do |config|
|
43
|
+
config.logger = :default # Use Lumberjack with default settings
|
44
|
+
config.transport = SmartMessage::Transport::StdoutTransport.new(loopback: true)
|
45
|
+
config.serializer = SmartMessage::Serializer::Json.new
|
46
|
+
end
|
47
|
+
|
48
|
+
puts " Configured Logger: #{SmartMessage::Logger.default.class}"
|
49
|
+
puts " Log File: #{SmartMessage::Logger.default.log_file rescue 'N/A'}"
|
50
|
+
puts " Configured Transport: #{SmartMessage::Transport.default.class}"
|
51
|
+
puts " Configured Serializer: #{SmartMessage::Serializer.default.class}"
|
52
|
+
puts
|
53
|
+
|
54
|
+
# Example 4: Message classes automatically use global configuration
|
55
|
+
puts "4. Message Classes Using Global Configuration:"
|
56
|
+
|
57
|
+
class NotificationMessage < SmartMessage::Base
|
58
|
+
property :recipient
|
59
|
+
property :message
|
60
|
+
property :priority, default: 'normal'
|
61
|
+
|
62
|
+
# No config block needed - automatically uses global configuration!
|
63
|
+
|
64
|
+
def self.process(wrapper)
|
65
|
+
message_header, message_payload = wrapper.split
|
66
|
+
data = JSON.parse(message_payload)
|
67
|
+
|
68
|
+
priority_emoji = case data['priority']
|
69
|
+
when 'high' then '🔴'
|
70
|
+
when 'medium' then '🟡'
|
71
|
+
else '🟢'
|
72
|
+
end
|
73
|
+
|
74
|
+
puts "#{priority_emoji} Notification: #{data['message']} (to: #{data['recipient']})"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class OrderStatusMessage < SmartMessage::Base
|
79
|
+
property :order_id
|
80
|
+
property :status
|
81
|
+
property :customer_id
|
82
|
+
|
83
|
+
# Also uses global configuration automatically
|
84
|
+
|
85
|
+
def self.process(wrapper)
|
86
|
+
message_header, message_payload = wrapper.split
|
87
|
+
data = JSON.parse(message_payload)
|
88
|
+
|
89
|
+
status_emoji = case data['status']
|
90
|
+
when 'confirmed' then '✅'
|
91
|
+
when 'shipped' then '📦'
|
92
|
+
when 'delivered' then '🎉'
|
93
|
+
when 'cancelled' then '❌'
|
94
|
+
else '⏳'
|
95
|
+
end
|
96
|
+
|
97
|
+
puts "#{status_emoji} Order #{data['order_id']}: #{data['status']}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Subscribe to messages to see them in action
|
102
|
+
NotificationMessage.subscribe
|
103
|
+
OrderStatusMessage.subscribe
|
104
|
+
|
105
|
+
puts " Message classes configured automatically!"
|
106
|
+
puts
|
107
|
+
|
108
|
+
# Example 4: Creating and publishing messages
|
109
|
+
puts "4. Publishing Messages (using global configuration):"
|
110
|
+
|
111
|
+
notification = NotificationMessage.new(
|
112
|
+
recipient: "admin@example.com",
|
113
|
+
message: "System maintenance scheduled for tonight",
|
114
|
+
priority: "high",
|
115
|
+
from: "SystemService"
|
116
|
+
)
|
117
|
+
|
118
|
+
order_status = OrderStatusMessage.new(
|
119
|
+
order_id: "ORD-12345",
|
120
|
+
status: "shipped",
|
121
|
+
customer_id: "CUST-001",
|
122
|
+
from: "OrderService"
|
123
|
+
)
|
124
|
+
|
125
|
+
puts "\n--- Publishing Messages ---"
|
126
|
+
notification.publish
|
127
|
+
order_status.publish
|
128
|
+
|
129
|
+
# Give time for async processing
|
130
|
+
sleep(0.5)
|
131
|
+
|
132
|
+
puts
|
133
|
+
|
134
|
+
# Example 5: Individual classes can still override global configuration
|
135
|
+
puts "5. Overriding Global Configuration for Specific Classes:"
|
136
|
+
|
137
|
+
class SpecialMessage < SmartMessage::Base
|
138
|
+
property :content
|
139
|
+
|
140
|
+
# Override just the logger, keep global transport and serializer
|
141
|
+
config do
|
142
|
+
logger SmartMessage::Logger::Default.new(log_file: STDERR, level: Logger::WARN)
|
143
|
+
# transport and serializer still use global configuration
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.process(wrapper)
|
147
|
+
message_header, message_payload = wrapper.split
|
148
|
+
data = JSON.parse(message_payload)
|
149
|
+
puts "⭐ Special processing: #{data['content']}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
SpecialMessage.subscribe
|
154
|
+
|
155
|
+
special = SpecialMessage.new(
|
156
|
+
content: "This uses custom logger but global transport/serializer",
|
157
|
+
from: "SpecialService"
|
158
|
+
)
|
159
|
+
|
160
|
+
puts " SpecialMessage logger: #{SpecialMessage.logger.class}"
|
161
|
+
puts " (Should be SmartMessage::Logger::Default with STDERR output)"
|
162
|
+
|
163
|
+
special.publish
|
164
|
+
sleep(0.5)
|
165
|
+
|
166
|
+
puts
|
167
|
+
|
168
|
+
# Example 6: Resetting configuration
|
169
|
+
puts "6. Resetting to Framework Defaults:"
|
170
|
+
SmartMessage.reset_configuration!
|
171
|
+
|
172
|
+
puts " After reset:"
|
173
|
+
puts " Logger: #{SmartMessage::Logger.default.class}"
|
174
|
+
puts " Transport: #{SmartMessage::Transport.default.class}"
|
175
|
+
puts " Serializer: #{SmartMessage::Serializer.default.class}"
|
176
|
+
|
177
|
+
puts "\n✨ Global Configuration Example Complete!"
|
178
|
+
puts
|
179
|
+
puts "Key Benefits:"
|
180
|
+
puts "• Set defaults once for entire application"
|
181
|
+
puts "• All message classes inherit global configuration automatically"
|
182
|
+
puts "• Individual classes can still override when needed"
|
183
|
+
puts "• Clean, centralized configuration management"
|
184
|
+
puts "• No need for repetitive config blocks in every message class"
|
185
|
+
puts "• Easy integration with Rails.logger or any other logger"
|
186
|
+
puts
|
187
|
+
puts "Configuration Options Summary:"
|
188
|
+
puts " # No configuration = NO LOGGING (new default behavior)"
|
189
|
+
puts " # No SmartMessage.configure block needed"
|
190
|
+
puts
|
191
|
+
puts " # String path = Lumberjack logger with that file"
|
192
|
+
puts " SmartMessage.configure do |config|"
|
193
|
+
puts " config.logger = 'log/my_app.log' # String path"
|
194
|
+
puts " end"
|
195
|
+
puts
|
196
|
+
puts " # STDOUT/STDERR = Lumberjack logger to console"
|
197
|
+
puts " SmartMessage.configure do |config|"
|
198
|
+
puts " config.logger = STDOUT # Log to STDOUT"
|
199
|
+
puts " config.logger = STDERR # Log to STDERR"
|
200
|
+
puts " end"
|
201
|
+
puts
|
202
|
+
puts " # :default symbol = Lumberjack with framework defaults"
|
203
|
+
puts " SmartMessage.configure do |config|"
|
204
|
+
puts " config.logger = :default # Framework default (file)"
|
205
|
+
puts " end"
|
206
|
+
puts
|
207
|
+
puts " # Custom logger object = Use that logger"
|
208
|
+
puts " SmartMessage.configure do |config|"
|
209
|
+
puts " config.logger = Rails.logger # Rails logger"
|
210
|
+
puts " config.logger = MyApp::Logger.new # Custom logger"
|
211
|
+
puts " end"
|
212
|
+
puts
|
213
|
+
puts " # Explicit nil = No logging (same as no configuration)"
|
214
|
+
puts " SmartMessage.configure do |config|"
|
215
|
+
puts " config.logger = nil # Explicit no logging"
|
216
|
+
puts " end"
|
217
|
+
|
218
|
+
# Clean up test file
|
219
|
+
File.delete('test_config.rb') if File.exist?('test_config.rb')
|
data/examples/README.md
CHANGED
@@ -16,6 +16,10 @@ ruby 05_proc_handlers.rb
|
|
16
16
|
ruby 06_custom_logger_example.rb
|
17
17
|
ruby 07_error_handling_scenarios.rb
|
18
18
|
ruby 08_entity_addressing.rb
|
19
|
+
ruby 09_regex_filtering_microservices.rb
|
20
|
+
ruby 10_header_block_configuration.rb
|
21
|
+
ruby 11_global_configuration_example.rb
|
22
|
+
ruby show_logger.rb
|
19
23
|
```
|
20
24
|
|
21
25
|
## Examples Overview
|
@@ -266,6 +270,73 @@ payment.publish
|
|
266
270
|
- **Runtime Configuration**: Dynamic addressing based on conditions
|
267
271
|
- **Integration Patterns**: Gateway support for external systems
|
268
272
|
|
273
|
+
---
|
274
|
+
|
275
|
+
### 10. Header Block Configuration (Addressing DSL)
|
276
|
+
**File:** `10_header_block_configuration.rb`
|
277
|
+
|
278
|
+
**Scenario:** Comprehensive demonstration of SmartMessage's flexible header configuration options, showing three different methods for setting addressing fields.
|
279
|
+
|
280
|
+
**Key Features:**
|
281
|
+
- Direct class methods for addressing configuration
|
282
|
+
- Header block DSL for clean, grouped configuration
|
283
|
+
- Mixed approach combining both methods
|
284
|
+
- Instance-level addressing overrides with method chaining
|
285
|
+
- Setter syntax for addressing fields
|
286
|
+
- Automatic header synchronization with instance values
|
287
|
+
- Configuration checking and validation methods
|
288
|
+
|
289
|
+
**Configuration Methods Demonstrated:**
|
290
|
+
```ruby
|
291
|
+
# Method 1: Direct class methods
|
292
|
+
class DirectMethodMessage < SmartMessage::Base
|
293
|
+
from 'service-a'
|
294
|
+
to 'service-b'
|
295
|
+
reply_to 'service-a-callback'
|
296
|
+
end
|
297
|
+
|
298
|
+
# Method 2: Header block DSL
|
299
|
+
class HeaderBlockMessage < SmartMessage::Base
|
300
|
+
header do
|
301
|
+
from 'service-x'
|
302
|
+
to 'service-y'
|
303
|
+
reply_to 'service-x-callback'
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
# Method 3: Mixed approach
|
308
|
+
class MixedConfigMessage < SmartMessage::Base
|
309
|
+
header do
|
310
|
+
from 'mixed-service'
|
311
|
+
to 'target-service'
|
312
|
+
end
|
313
|
+
reply_to 'mixed-callback' # Outside block
|
314
|
+
end
|
315
|
+
```
|
316
|
+
|
317
|
+
**Instance-Level Features:**
|
318
|
+
- **Method Chaining**: `msg.from('sender').to('recipient').reply_to('callback')`
|
319
|
+
- **Setter Syntax**: `msg.from = 'sender'`, `msg.to = 'recipient'`
|
320
|
+
- **Shortcut Accessors**: `msg.from`, `msg.to`, `msg.reply_to`
|
321
|
+
- **Header Access**: `msg._sm_header.from`, `msg._sm_header.to`
|
322
|
+
- **Configuration Checks**: `msg.from_configured?`, `msg.to_missing?`
|
323
|
+
- **Reset Methods**: `msg.reset_from`, `msg.reset_to`, `msg.reset_reply_to`
|
324
|
+
|
325
|
+
**What You'll Learn:**
|
326
|
+
- How to choose the best configuration method for your use case
|
327
|
+
- Benefits of header block DSL for grouped configuration
|
328
|
+
- Dynamic addressing overrides at runtime
|
329
|
+
- Three ways to access addressing values
|
330
|
+
- How headers automatically sync with instance changes
|
331
|
+
- Configuration validation and checking methods
|
332
|
+
|
333
|
+
**Benefits:**
|
334
|
+
- **Clean Syntax**: Header block groups related configuration
|
335
|
+
- **Flexibility**: Multiple configuration approaches to suit different styles
|
336
|
+
- **Runtime Control**: Instance-level overrides for dynamic routing
|
337
|
+
- **Consistency**: Headers stay synchronized with instance values
|
338
|
+
- **Validation**: Built-in methods to check configuration state
|
339
|
+
|
269
340
|
## Message Patterns Demonstrated
|
270
341
|
|
271
342
|
### Request-Response Pattern
|
@@ -471,6 +542,37 @@ class MyCustomTransport < SmartMessage::Transport::Base
|
|
471
542
|
end
|
472
543
|
```
|
473
544
|
|
545
|
+
---
|
546
|
+
|
547
|
+
### Show Logger Demonstration
|
548
|
+
**File:** `show_logger.rb`
|
549
|
+
|
550
|
+
**Scenario:** Comprehensive demonstration of SmartMessage's enhanced logging capabilities, showing how applications can use the SmartMessage logger directly and configure various Lumberjack options.
|
551
|
+
|
552
|
+
**Key Features:**
|
553
|
+
- Colorized console output for different log levels
|
554
|
+
- JSON and text log formatting
|
555
|
+
- File-based logging with rolling (size and date-based)
|
556
|
+
- Application logger patterns and direct logger usage
|
557
|
+
- Multiple logger configurations
|
558
|
+
- Integration with SmartMessage classes
|
559
|
+
|
560
|
+
**What You'll Learn:**
|
561
|
+
- How to configure SmartMessage's global logger settings
|
562
|
+
- Different log output formats (text vs JSON)
|
563
|
+
- Colorized logging for console output
|
564
|
+
- File rolling strategies for production use
|
565
|
+
- How to use the SmartMessage logger directly in applications
|
566
|
+
- Best practices for structured logging
|
567
|
+
- Integration patterns between application code and SmartMessage classes
|
568
|
+
|
569
|
+
**Demonstrates:**
|
570
|
+
- `SmartMessage.configure` block usage for logger configuration
|
571
|
+
- `log_level`, `log_format`, `log_colorize`, and `log_options` settings
|
572
|
+
- Direct access to `SmartMessage.configuration.default_logger`
|
573
|
+
- Creating multiple logger instances with different configurations
|
574
|
+
- Practical application patterns using the logger
|
575
|
+
|
474
576
|
## Production Considerations
|
475
577
|
|
476
578
|
When adapting these examples for production:
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{"timestamp":"2025-08-19T16:03:52-05:00","header":{"uuid":"ecb4c4f9-e9a7-47fd-918a-8dc5087218d6","message_class":"OrderMessage","published_at":"2025-08-19T16:03:52.374-05:00","publisher_pid":16266,"version":1,"from":"OrderService","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"order_id\":\"ORD-1001\",\"customer_id\":\"CUST-001\",\"amount\":99.99,\"currency\":\"USD\",\"payment_method\":\"credit_card\",\"items\":[\"Widget A\",\"Widget B\"]}","payload_format":"json","error":"wrong number of arguments (given 1, expected 2)","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
2
|
+
{"timestamp":"2025-08-19T16:03:52-05:00","header":{"uuid":"40dce8a2-1723-48f5-ad01-fe49814991a2","message_class":"OrderMessage","published_at":"2025-08-19T16:03:52.889-05:00","publisher_pid":16266,"version":1,"from":"OrderService","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"order_id\":\"ORD-1002\",\"customer_id\":\"CUST-002\",\"amount\":1299.99,\"currency\":\"USD\",\"payment_method\":\"debit_card\",\"items\":[\"Premium Widget\",\"Extended Warranty\"]}","payload_format":"json","error":"wrong number of arguments (given 1, expected 2)","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
3
|
+
{"timestamp":"2025-08-19T16:03:53-05:00","header":{"uuid":"0e1a228b-4069-4c05-b1ed-18193174d773","message_class":"OrderMessage","published_at":"2025-08-19T16:03:53.397-05:00","publisher_pid":16266,"version":1,"from":"OrderService","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"order_id\":\"ORD-1003\",\"customer_id\":\"CUST-003\",\"amount\":45.5,\"currency\":\"USD\",\"payment_method\":\"paypal\",\"items\":[\"Small Widget\"]}","payload_format":"json","error":"wrong number of arguments (given 1, expected 2)","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
4
|
+
{"timestamp":"2025-08-19T16:04:01-05:00","header":{"uuid":"60ca2ca3-8185-4946-ae20-85269073ce3e","message_class":"UserEventMessage","published_at":"2025-08-19T16:04:01.582-05:00","publisher_pid":16396,"version":1,"from":"UserManager","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"event_id\":\"EVT-1001\",\"event_type\":\"user_registered\",\"user_id\":\"USER-101\",\"user_email\":\"alice@example.com\",\"user_name\":\"Alice Johnson\",\"timestamp\":\"2025-08-19T16:04:01-05:00\",\"metadata\":{\"source\":\"web_registration\"}}","payload_format":"json","error":"wrong number of arguments (given 1, expected 2)","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
5
|
+
{"timestamp":"2025-08-19T16:23:07-05:00","header":{"uuid":"ebd1f61b-e5d9-48f4-a787-e1f9f4e09578","message_class":"SystemNotificationMessage","published_at":"2025-08-19T16:23:07.222-05:00","publisher_pid":24163,"version":1,"from":"user-001","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"notification_id\":\"NOTIF-1755638587-564\",\"room_id\":\"general\",\"notification_type\":\"user_joined\",\"content\":\"Alice joined the room\",\"timestamp\":\"2025-08-19T16:23:07-05:00\",\"metadata\":{\"triggered_by\":\"user-001\"}}","payload_format":"json","error":"undefined method 'handle_system_notification_user-001' for class 'HumanChatAgent'","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
6
|
+
{"timestamp":"2025-08-19T16:25:50-05:00","header":{"uuid":"e722ef85-7168-42e2-94c2-cc55c1ca6784","message_class":"PaymentMessage","published_at":"2025-08-19T16:25:50.310-05:00","publisher_pid":25696,"version":1,"from":"payment-service","to":"dev-payment-processor","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"service_id\":\"payment-core\",\"message_type\":\"transaction_complete\",\"data\":{\"merchant\":\"Online Store\"},\"environment\":\"dev\",\"timestamp\":\"2025-08-19T16:25:50-05:00\",\"transaction_id\":\"TXN-001\",\"amount\":99.99,\"currency\":\"USD\"}","payload_format":"json","error":"undefined method 'process_dev' for class 'PaymentMessage'","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
7
|
+
{"timestamp":"2025-08-19T16:25:50-05:00","header":{"uuid":"d36c3c66-bccc-49af-b919-b62bc6c9e1b2","message_class":"PaymentMessage","published_at":"2025-08-19T16:25:50.831-05:00","publisher_pid":25696,"version":1,"from":"payment-service","to":"prod-payment-processor","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"service_id\":\"payment-core\",\"message_type\":\"transaction_complete\",\"data\":{\"merchant\":\"Enterprise Store\"},\"environment\":\"prod\",\"timestamp\":\"2025-08-19T16:25:50-05:00\",\"transaction_id\":\"TXN-002\",\"amount\":299.99,\"currency\":\"USD\"}","payload_format":"json","error":"undefined method 'process_prod' for class 'PaymentMessage'","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
8
|
+
{"timestamp":"2025-08-19T16:25:52-05:00","header":{"uuid":"d3371fb3-ed6e-403c-8f3b-3b130958a013","message_class":"AlertMessage","published_at":"2025-08-19T16:25:52.351-05:00","publisher_pid":25696,"version":1,"from":"admin","to":"security-dashboard","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"service_id\":\"security-scanner\",\"message_type\":\"security_alert\",\"data\":{\"attempts\":50,\"ip\":\"192.168.1.100\"},\"environment\":\"prod\",\"timestamp\":\"2025-08-19T16:25:52-05:00\",\"alert_level\":\"critical\",\"component\":\"authentication\",\"description\":\"Multiple failed login attempts detected\"}","payload_format":"json","error":"undefined method 'process_admin' for class 'AlertMessage'","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
9
|
+
{"timestamp":"2025-08-19T16:25:52-05:00","header":{"uuid":"46a5b557-540c-4d50-a1f9-030907ba6275","message_class":"AlertMessage","published_at":"2025-08-19T16:25:52.860-05:00","publisher_pid":25696,"version":1,"from":"system-metrics","to":"ops-dashboard","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"service_id\":\"system-monitor\",\"message_type\":\"resource_alert\",\"data\":{\"usage_percent\":85,\"threshold\":80},\"environment\":\"staging\",\"timestamp\":\"2025-08-19T16:25:52-05:00\",\"alert_level\":\"warning\",\"component\":\"memory\",\"description\":\"Memory usage above threshold\"}","payload_format":"json","error":"Circuit 'message_processor' is open","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
10
|
+
{"timestamp":"2025-08-19T16:25:52-05:00","header":{"uuid":"46a5b557-540c-4d50-a1f9-030907ba6275","message_class":"AlertMessage","published_at":"2025-08-19T16:25:52.860-05:00","publisher_pid":25696,"version":1,"from":"system-metrics","to":"ops-dashboard","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"service_id\":\"system-monitor\",\"message_type\":\"resource_alert\",\"data\":{\"usage_percent\":85,\"threshold\":80},\"environment\":\"staging\",\"timestamp\":\"2025-08-19T16:25:52-05:00\",\"alert_level\":\"warning\",\"component\":\"memory\",\"description\":\"Memory usage above threshold\"}","payload_format":"json","error":"Circuit 'message_processor' is open","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
11
|
+
{"timestamp":"2025-08-19T16:25:53-05:00","header":{"uuid":"8ebceac3-8c5d-4253-b2a2-ce754084c3c2","message_class":"OrderMessage","published_at":"2025-08-19T16:25:53.365-05:00","publisher_pid":25696,"version":1,"from":"admin-dashboard","to":"prod-fulfillment","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"service_id\":\"admin-portal\",\"message_type\":\"admin_order_override\",\"data\":{\"priority\":\"high\",\"reason\":\"VIP customer\"},\"environment\":\"prod\",\"timestamp\":\"2025-08-19T16:25:53-05:00\",\"order_id\":\"ORD-999\",\"customer_id\":\"ADMIN\",\"status\":\"expedited\"}","payload_format":"json","error":"Circuit 'message_processor' is open","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
12
|
+
{"timestamp":"2025-08-19T16:25:53-05:00","header":{"uuid":"8dfa4fed-f2df-4f66-81c2-963a97489a31","message_class":"PaymentMessage","published_at":"2025-08-19T16:25:53.873-05:00","publisher_pid":25696,"version":1,"from":"admin","serializer":"SmartMessage::Serializer::JSON"},"payload":"{\"service_id\":\"payment-system\",\"message_type\":\"system_maintenance\",\"data\":{\"message\":\"Scheduled maintenance in 30 minutes\",\"duration\":\"2 hours\",\"affected_services\":[\"payment\",\"billing\"]},\"environment\":\"prod\",\"timestamp\":\"2025-08-19T16:25:53-05:00\",\"transaction_id\":\"MAINT-001\",\"amount\":0,\"currency\":\"USD\"}","payload_format":"json","error":"Circuit 'message_processor' is open","retry_count":0,"transport":"circuit_breaker","stack_trace":null}
|
@@ -0,0 +1,135 @@
|
|
1
|
+
{
|
2
|
+
"benchmark_info": {
|
3
|
+
"timestamp": "2025-08-18T20:56:03-05:00",
|
4
|
+
"implementation": "ractor",
|
5
|
+
"ruby_version": "3.4.5",
|
6
|
+
"platform": "arm64-darwin24",
|
7
|
+
"processor_count": 12
|
8
|
+
},
|
9
|
+
"overall_stats": {
|
10
|
+
"total_runtime": 4.173938,
|
11
|
+
"memory_used_mb": 21.046875
|
12
|
+
},
|
13
|
+
"scenario_results": {
|
14
|
+
"cpu_light": {
|
15
|
+
"name": "CPU Light",
|
16
|
+
"messages_generated": 1000,
|
17
|
+
"messages_published": 1000,
|
18
|
+
"messages_processed": 1000,
|
19
|
+
"errors": 0,
|
20
|
+
"times": {
|
21
|
+
"total": 0.360609,
|
22
|
+
"publish": 0.139781,
|
23
|
+
"processing": 0.103401
|
24
|
+
},
|
25
|
+
"throughput": {
|
26
|
+
"messages_per_second": 2773.0866395458793,
|
27
|
+
"publish_rate": 7154.048118127643
|
28
|
+
},
|
29
|
+
"dispatcher_stats": {
|
30
|
+
"pool_size": null,
|
31
|
+
"queue_length": 0,
|
32
|
+
"completed_task_count": 1000,
|
33
|
+
"scheduled_task_count": 1000,
|
34
|
+
"running": true,
|
35
|
+
"implementation": "ractor"
|
36
|
+
}
|
37
|
+
},
|
38
|
+
"cpu_heavy": {
|
39
|
+
"name": "CPU Heavy",
|
40
|
+
"messages_generated": 500,
|
41
|
+
"messages_published": 500,
|
42
|
+
"messages_processed": 500,
|
43
|
+
"errors": 0,
|
44
|
+
"times": {
|
45
|
+
"total": 1.701841,
|
46
|
+
"publish": 0.487508,
|
47
|
+
"processing": 1.1547
|
48
|
+
},
|
49
|
+
"throughput": {
|
50
|
+
"messages_per_second": 293.7994795048421,
|
51
|
+
"publish_rate": 1025.624194885007
|
52
|
+
},
|
53
|
+
"dispatcher_stats": {
|
54
|
+
"pool_size": null,
|
55
|
+
"queue_length": 0,
|
56
|
+
"completed_task_count": 1500,
|
57
|
+
"scheduled_task_count": 1500,
|
58
|
+
"running": true,
|
59
|
+
"implementation": "ractor"
|
60
|
+
}
|
61
|
+
},
|
62
|
+
"io_light": {
|
63
|
+
"name": "I/O Light",
|
64
|
+
"messages_generated": 800,
|
65
|
+
"messages_published": 800,
|
66
|
+
"messages_processed": 800,
|
67
|
+
"errors": 0,
|
68
|
+
"times": {
|
69
|
+
"total": 0.880671,
|
70
|
+
"publish": 0.068458,
|
71
|
+
"processing": 0.724868
|
72
|
+
},
|
73
|
+
"throughput": {
|
74
|
+
"messages_per_second": 908.3982554211505,
|
75
|
+
"publish_rate": 11685.997253790645
|
76
|
+
},
|
77
|
+
"dispatcher_stats": {
|
78
|
+
"pool_size": null,
|
79
|
+
"queue_length": 0,
|
80
|
+
"completed_task_count": 2300,
|
81
|
+
"scheduled_task_count": 2300,
|
82
|
+
"running": true,
|
83
|
+
"implementation": "ractor"
|
84
|
+
}
|
85
|
+
},
|
86
|
+
"io_heavy": {
|
87
|
+
"name": "I/O Heavy",
|
88
|
+
"messages_generated": 200,
|
89
|
+
"messages_published": 200,
|
90
|
+
"messages_processed": 200,
|
91
|
+
"errors": 0,
|
92
|
+
"times": {
|
93
|
+
"total": 0.249395,
|
94
|
+
"publish": 0.015782,
|
95
|
+
"processing": 0.205659
|
96
|
+
},
|
97
|
+
"throughput": {
|
98
|
+
"messages_per_second": 801.9406964854949,
|
99
|
+
"publish_rate": 12672.665061462425
|
100
|
+
},
|
101
|
+
"dispatcher_stats": {
|
102
|
+
"pool_size": null,
|
103
|
+
"queue_length": 0,
|
104
|
+
"completed_task_count": 2500,
|
105
|
+
"scheduled_task_count": 2500,
|
106
|
+
"running": true,
|
107
|
+
"implementation": "ractor"
|
108
|
+
}
|
109
|
+
},
|
110
|
+
"mixed": {
|
111
|
+
"name": "Mixed Load",
|
112
|
+
"messages_generated": 600,
|
113
|
+
"messages_published": 600,
|
114
|
+
"messages_processed": 600,
|
115
|
+
"errors": 0,
|
116
|
+
"times": {
|
117
|
+
"total": 0.969969,
|
118
|
+
"publish": 0.145701,
|
119
|
+
"processing": 0.747523
|
120
|
+
},
|
121
|
+
"throughput": {
|
122
|
+
"messages_per_second": 618.5764699696589,
|
123
|
+
"publish_rate": 4118.022525583215
|
124
|
+
},
|
125
|
+
"dispatcher_stats": {
|
126
|
+
"pool_size": null,
|
127
|
+
"queue_length": 0,
|
128
|
+
"completed_task_count": 3100,
|
129
|
+
"scheduled_task_count": 3100,
|
130
|
+
"running": true,
|
131
|
+
"implementation": "ractor"
|
132
|
+
}
|
133
|
+
}
|
134
|
+
}
|
135
|
+
}
|
@@ -0,0 +1,135 @@
|
|
1
|
+
{
|
2
|
+
"benchmark_info": {
|
3
|
+
"timestamp": "2025-08-18T20:58:31-05:00",
|
4
|
+
"implementation": "ractor",
|
5
|
+
"ruby_version": "3.4.5",
|
6
|
+
"platform": "arm64-darwin24",
|
7
|
+
"processor_count": 12
|
8
|
+
},
|
9
|
+
"overall_stats": {
|
10
|
+
"total_runtime": 4.174644,
|
11
|
+
"memory_used_mb": 23.53125
|
12
|
+
},
|
13
|
+
"scenario_results": {
|
14
|
+
"cpu_light": {
|
15
|
+
"name": "CPU Light",
|
16
|
+
"messages_generated": 1000,
|
17
|
+
"messages_published": 1000,
|
18
|
+
"messages_processed": 1000,
|
19
|
+
"errors": 0,
|
20
|
+
"times": {
|
21
|
+
"total": 0.353973,
|
22
|
+
"publish": 0.135409,
|
23
|
+
"processing": 0.106285
|
24
|
+
},
|
25
|
+
"throughput": {
|
26
|
+
"messages_per_second": 2825.0742288253628,
|
27
|
+
"publish_rate": 7385.033491126882
|
28
|
+
},
|
29
|
+
"dispatcher_stats": {
|
30
|
+
"pool_size": null,
|
31
|
+
"queue_length": 0,
|
32
|
+
"completed_task_count": 1000,
|
33
|
+
"scheduled_task_count": 1000,
|
34
|
+
"running": true,
|
35
|
+
"implementation": "ractor"
|
36
|
+
}
|
37
|
+
},
|
38
|
+
"cpu_heavy": {
|
39
|
+
"name": "CPU Heavy",
|
40
|
+
"messages_generated": 500,
|
41
|
+
"messages_published": 500,
|
42
|
+
"messages_processed": 500,
|
43
|
+
"errors": 0,
|
44
|
+
"times": {
|
45
|
+
"total": 1.76826,
|
46
|
+
"publish": 0.427835,
|
47
|
+
"processing": 1.265818
|
48
|
+
},
|
49
|
+
"throughput": {
|
50
|
+
"messages_per_second": 282.76384694558493,
|
51
|
+
"publish_rate": 1168.6748395993782
|
52
|
+
},
|
53
|
+
"dispatcher_stats": {
|
54
|
+
"pool_size": null,
|
55
|
+
"queue_length": 0,
|
56
|
+
"completed_task_count": 1500,
|
57
|
+
"scheduled_task_count": 1500,
|
58
|
+
"running": true,
|
59
|
+
"implementation": "ractor"
|
60
|
+
}
|
61
|
+
},
|
62
|
+
"io_light": {
|
63
|
+
"name": "I/O Light",
|
64
|
+
"messages_generated": 800,
|
65
|
+
"messages_published": 800,
|
66
|
+
"messages_processed": 800,
|
67
|
+
"errors": 0,
|
68
|
+
"times": {
|
69
|
+
"total": 0.893786,
|
70
|
+
"publish": 0.065332,
|
71
|
+
"processing": 0.731431
|
72
|
+
},
|
73
|
+
"throughput": {
|
74
|
+
"messages_per_second": 895.068841982309,
|
75
|
+
"publish_rate": 12245.14786016041
|
76
|
+
},
|
77
|
+
"dispatcher_stats": {
|
78
|
+
"pool_size": null,
|
79
|
+
"queue_length": 0,
|
80
|
+
"completed_task_count": 2300,
|
81
|
+
"scheduled_task_count": 2300,
|
82
|
+
"running": true,
|
83
|
+
"implementation": "ractor"
|
84
|
+
}
|
85
|
+
},
|
86
|
+
"io_heavy": {
|
87
|
+
"name": "I/O Heavy",
|
88
|
+
"messages_generated": 200,
|
89
|
+
"messages_published": 200,
|
90
|
+
"messages_processed": 200,
|
91
|
+
"errors": 0,
|
92
|
+
"times": {
|
93
|
+
"total": 0.274932,
|
94
|
+
"publish": 0.017833,
|
95
|
+
"processing": 0.210557
|
96
|
+
},
|
97
|
+
"throughput": {
|
98
|
+
"messages_per_second": 727.4526064626889,
|
99
|
+
"publish_rate": 11215.162900241125
|
100
|
+
},
|
101
|
+
"dispatcher_stats": {
|
102
|
+
"pool_size": null,
|
103
|
+
"queue_length": 0,
|
104
|
+
"completed_task_count": 2500,
|
105
|
+
"scheduled_task_count": 2500,
|
106
|
+
"running": true,
|
107
|
+
"implementation": "ractor"
|
108
|
+
}
|
109
|
+
},
|
110
|
+
"mixed": {
|
111
|
+
"name": "Mixed Load",
|
112
|
+
"messages_generated": 600,
|
113
|
+
"messages_published": 600,
|
114
|
+
"messages_processed": 600,
|
115
|
+
"errors": 0,
|
116
|
+
"times": {
|
117
|
+
"total": 0.870865,
|
118
|
+
"publish": 0.145127,
|
119
|
+
"processing": 0.625774
|
120
|
+
},
|
121
|
+
"throughput": {
|
122
|
+
"messages_per_second": 688.9701618505738,
|
123
|
+
"publish_rate": 4134.309949216893
|
124
|
+
},
|
125
|
+
"dispatcher_stats": {
|
126
|
+
"pool_size": null,
|
127
|
+
"queue_length": 0,
|
128
|
+
"completed_task_count": 3100,
|
129
|
+
"scheduled_task_count": 3100,
|
130
|
+
"running": true,
|
131
|
+
"implementation": "ractor"
|
132
|
+
}
|
133
|
+
}
|
134
|
+
}
|
135
|
+
}
|