smart_message 0.0.12 → 0.0.13
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/CHANGELOG.md +35 -1
- data/Gemfile.lock +5 -5
- data/docs/core-concepts/architecture.md +5 -10
- data/docs/getting-started/examples.md +0 -12
- data/docs/getting-started/quick-start.md +4 -9
- data/docs/index.md +4 -4
- data/docs/reference/serializers.md +160 -488
- data/docs/reference/transports.md +1 -125
- data/docs/transports/redis-transport-comparison.md +215 -350
- data/docs/transports/redis-transport.md +3 -22
- data/examples/README.md +6 -9
- data/examples/city_scenario/README.md +1 -1
- data/examples/city_scenario/messages/emergency_911_message.rb +0 -1
- data/examples/city_scenario/messages/emergency_resolved_message.rb +0 -1
- data/examples/city_scenario/messages/fire_dispatch_message.rb +0 -1
- data/examples/city_scenario/messages/fire_emergency_message.rb +0 -1
- data/examples/city_scenario/messages/health_check_message.rb +0 -1
- data/examples/city_scenario/messages/health_status_message.rb +0 -1
- data/examples/city_scenario/messages/police_dispatch_message.rb +0 -1
- data/examples/city_scenario/messages/silent_alarm_message.rb +0 -1
- data/examples/memory/01_message_deduplication_demo.rb +0 -2
- data/examples/memory/02_dead_letter_queue_demo.rb +0 -3
- data/examples/memory/03_point_to_point_orders.rb +0 -2
- data/examples/memory/04_publish_subscribe_events.rb +0 -1
- data/examples/memory/05_many_to_many_chat.rb +0 -3
- data/examples/memory/07_proc_handlers_demo.rb +0 -1
- data/examples/memory/08_custom_logger_demo.rb +0 -4
- data/examples/memory/09_error_handling_demo.rb +0 -3
- data/examples/memory/10_entity_addressing_basic.rb +0 -6
- data/examples/memory/11_entity_addressing_with_filtering.rb +0 -4
- data/examples/memory/12_regex_filtering_microservices.rb +0 -1
- data/examples/memory/13_header_block_configuration.rb +0 -5
- data/examples/memory/14_global_configuration_demo.rb +0 -2
- data/examples/memory/15_logger_demo.rb +0 -1
- data/examples/memory/README.md +3 -3
- data/examples/redis/01_smart_home_iot_demo.rb +0 -4
- data/examples/redis/README.md +0 -2
- data/lib/smart_message/base.rb +19 -10
- data/lib/smart_message/configuration.rb +2 -23
- data/lib/smart_message/dead_letter_queue.rb +1 -1
- data/lib/smart_message/messaging.rb +3 -62
- data/lib/smart_message/plugins.rb +1 -42
- data/lib/smart_message/transport/base.rb +42 -8
- data/lib/smart_message/transport/memory_transport.rb +23 -4
- data/lib/smart_message/transport/redis_transport.rb +11 -0
- data/lib/smart_message/transport/registry.rb +0 -1
- data/lib/smart_message/transport/stdout_transport.rb +28 -10
- data/lib/smart_message/transport.rb +0 -1
- data/lib/smart_message/version.rb +1 -1
- metadata +2 -28
- data/docs/guides/redis-queue-getting-started.md +0 -697
- data/docs/guides/redis-queue-patterns.md +0 -889
- data/docs/guides/redis-queue-production.md +0 -1091
- data/docs/transports/redis-enhanced-transport.md +0 -524
- data/docs/transports/redis-queue-transport.md +0 -1304
- data/examples/redis_enhanced/README.md +0 -319
- data/examples/redis_enhanced/enhanced_01_basic_patterns.rb +0 -233
- data/examples/redis_enhanced/enhanced_02_fluent_api.rb +0 -331
- data/examples/redis_enhanced/enhanced_03_dual_publishing.rb +0 -281
- data/examples/redis_enhanced/enhanced_04_advanced_routing.rb +0 -419
- data/examples/redis_queue/01_basic_messaging.rb +0 -221
- data/examples/redis_queue/01_comprehensive_examples.rb +0 -508
- data/examples/redis_queue/02_pattern_routing.rb +0 -405
- data/examples/redis_queue/03_fluent_api.rb +0 -422
- data/examples/redis_queue/04_load_balancing.rb +0 -486
- data/examples/redis_queue/05_microservices.rb +0 -735
- data/examples/redis_queue/06_emergency_alerts.rb +0 -777
- data/examples/redis_queue/07_queue_management.rb +0 -587
- data/examples/redis_queue/README.md +0 -366
- data/examples/redis_queue/enhanced_01_basic_patterns.rb +0 -233
- data/examples/redis_queue/enhanced_02_fluent_api.rb +0 -331
- data/examples/redis_queue/enhanced_03_dual_publishing.rb +0 -281
- data/examples/redis_queue/enhanced_04_advanced_routing.rb +0 -419
- data/examples/redis_queue/redis_queue_architecture.svg +0 -148
- data/lib/smart_message/transport/redis_enhanced_transport.rb +0 -399
- data/lib/smart_message/transport/redis_queue_transport.rb +0 -555
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38b75aa70a9ab79b0fd9ac311d7e5634491789e5813161630ff7e04f17d61373
|
4
|
+
data.tar.gz: 8196665b3a660cfaad1c30753697f020c4a54b50c25d23be6f6c3c6ad9149e38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 876f94f732eb022c568a200747438ab6a0938602735f89601fc7c9e48f34bf21791c75608b2d877475d9190a9629974a63448f5ceb6eeb24bf073b0cc1e4ee19
|
7
|
+
data.tar.gz: 310150522f4d6561c40e7322072a75778867b643b5eb6b79364b750a39689e27cbfd7c7022ae0f0c8a44ae9a850549c02e94005930d4b878ba75cb1eb1192a58
|
data/CHANGELOG.md
CHANGED
@@ -7,10 +7,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [0.0.13] 2025-09-10
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
- **BREAKING: Transport-Level Serialization Architecture**: Major architectural rework moving serializer responsibility from message classes to transport layer
|
14
|
+
- **Core Change**: Serializers now associated with transports instead of message classes, enabling different transports to use different serialization formats
|
15
|
+
- **Message Structure**: Eliminated wrapper objects in favor of flat message structure with `_sm_header` routing metadata
|
16
|
+
- **Serialization Format**: Messages now serialized as single JSON objects containing both header and payload data (e.g., `{"_sm_header": {...}, "content": "value", "property": "data"}`)
|
17
|
+
- **Transport Flexibility**: Each transport can now use its own serializer (JSON, MessagePack, etc.) independently
|
18
|
+
- **Backward Compatibility**: Added `_sm_payload` and `split` methods to maintain compatibility with existing proc handlers
|
19
|
+
- **Performance**: Simplified message processing pipeline with direct message instance passing instead of complex wrapper handling
|
20
|
+
|
21
|
+
### Fixed
|
22
|
+
- **Message Reconstruction**: Fixed critical bug in `SmartMessage::Base#initialize` where payload properties were not properly extracted from flat serialized structure
|
23
|
+
- **Root Cause**: Initialization logic looked for `props[:_sm_payload]` but flat structure stores properties directly in `props`
|
24
|
+
- **Solution**: Changed to `payload_props = props.except(:_sm_header)` to extract all non-header properties
|
25
|
+
- **Impact**: Proc handlers now receive correct message content, resolving nil property values in `_sm_payload`
|
26
|
+
- **Circuit Breaker Test Compatibility**: Updated circuit breaker tests to use new transport method signatures
|
27
|
+
- **Issue**: Tests were calling `transport.publish(header, payload)` with two arguments
|
28
|
+
- **Fix**: Updated to `transport.publish(message_instance)` with single message parameter
|
29
|
+
- **Result**: All circuit breaker tests now pass with new architecture
|
30
|
+
- **Deduplication Test Format**: Updated deduplication tests from old wrapper format to new flat structure
|
31
|
+
- **Changed**: `_sm_payload: { content: "value" }` → `content: "value"`
|
32
|
+
- **Maintained**: Full deduplication functionality with handler-scoped DDQ system
|
33
|
+
|
34
|
+
### Enhanced
|
35
|
+
- **Transport Serialization Control**: Each transport implementation can now specify its preferred serializer
|
36
|
+
- **Memory Transport**: Returns message objects directly without serialization for performance
|
37
|
+
- **STDOUT Transport**: Uses JSON serializer with pretty printing for human readability
|
38
|
+
- **Redis Transport**: Uses MessagePack with JSON fallback for efficient network transmission
|
39
|
+
- **Message Processing Pipeline**: Streamlined architecture with direct message instance routing
|
40
|
+
- **Eliminated**: Complex wrapper object creation and management overhead
|
41
|
+
- **Simplified**: Transport `receive` method now directly reconstructs message instances from flat data
|
42
|
+
- **Improved**: Cleaner separation between transport concerns and message processing logic
|
43
|
+
|
10
44
|
### Added
|
11
45
|
- **Emergency Services Multi-Program Demo**: Complete emergency dispatch simulation system
|
12
46
|
- Added comprehensive emergency services message definitions with validation
|
13
|
-
- Emergency Dispatch Center (911) routing calls to appropriate departments
|
47
|
+
- Emergency Dispatch Center (911) routing calls to appropriate departments
|
14
48
|
- Fire Department, Police Department, and Health Department service implementations
|
15
49
|
- AI-powered visitor generating realistic emergency scenarios with retry logic
|
16
50
|
- Health monitoring system across all city services with status reporting
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
smart_message (0.0.
|
4
|
+
smart_message (0.0.13)
|
5
5
|
activesupport
|
6
6
|
async
|
7
7
|
async-redis
|
@@ -30,7 +30,7 @@ GEM
|
|
30
30
|
tzinfo (~> 2.0, >= 2.0.5)
|
31
31
|
uri (>= 0.13.1)
|
32
32
|
amazing_print (1.8.1)
|
33
|
-
async (2.
|
33
|
+
async (2.31.0)
|
34
34
|
console (~> 1.29)
|
35
35
|
fiber-annotation
|
36
36
|
io-event (~> 1.11)
|
@@ -69,12 +69,12 @@ GEM
|
|
69
69
|
i18n (1.14.7)
|
70
70
|
concurrent-ruby (~> 1.0)
|
71
71
|
io-endpoint (0.15.2)
|
72
|
-
io-event (1.
|
72
|
+
io-event (1.14.0)
|
73
73
|
io-stream (0.10.0)
|
74
74
|
json (2.13.2)
|
75
75
|
logger (1.7.0)
|
76
76
|
lumberjack (1.4.1)
|
77
|
-
metrics (0.14.
|
77
|
+
metrics (0.14.1)
|
78
78
|
minitest (5.25.5)
|
79
79
|
minitest-power_assert (0.3.1)
|
80
80
|
minitest
|
@@ -95,7 +95,7 @@ GEM
|
|
95
95
|
shoulda-matchers (4.5.1)
|
96
96
|
activesupport (>= 4.2.0)
|
97
97
|
state_machines (0.100.1)
|
98
|
-
traces (0.18.
|
98
|
+
traces (0.18.2)
|
99
99
|
tzinfo (2.0.6)
|
100
100
|
concurrent-ruby (~> 1.0)
|
101
101
|
uri (1.0.3)
|
@@ -9,10 +9,10 @@ SmartMessage is designed around the principle that **messages should be independ
|
|
9
9
|
### Core Principles
|
10
10
|
|
11
11
|
1. **Separation of Concerns**: Message content, transport, and serialization are independent
|
12
|
-
2. **Plugin Architecture**: Pluggable transports
|
12
|
+
2. **Plugin Architecture**: Pluggable transports
|
13
13
|
3. **Dual Configuration**: Both class-level and instance-level configuration
|
14
14
|
4. **Thread Safety**: Concurrent message processing with thread pools
|
15
|
-
5. **Gateway Support**: Messages can flow between different transports
|
15
|
+
5. **Gateway Support**: Messages can flow between different transports
|
16
16
|
|
17
17
|
## Architecture Overview
|
18
18
|
|
@@ -26,7 +26,7 @@ The foundation class that all messages inherit from, built on `Hashie::Dash`.
|
|
26
26
|
|
27
27
|
**Key Responsibilities:**
|
28
28
|
- Property management and validation
|
29
|
-
- Plugin configuration (transport,
|
29
|
+
- Plugin configuration (transport, logger)
|
30
30
|
- Message lifecycle management
|
31
31
|
- Header generation and management
|
32
32
|
|
@@ -40,7 +40,6 @@ class MyMessage < SmartMessage::Base
|
|
40
40
|
|
41
41
|
config do
|
42
42
|
transport MyTransport.new
|
43
|
-
serializer MySerializer.new
|
44
43
|
end
|
45
44
|
end
|
46
45
|
```
|
@@ -163,7 +162,6 @@ puts header.from # "payment-service"
|
|
163
162
|
puts header.to # "order-service"
|
164
163
|
puts header.reply_to # "payment-service" (defaults to from)
|
165
164
|
puts header.version # 1
|
166
|
-
puts header.serializer # "SmartMessage::Serializer::JSON"
|
167
165
|
```
|
168
166
|
|
169
167
|
## Message Lifecycle
|
@@ -176,7 +174,6 @@ class OrderMessage < SmartMessage::Base
|
|
176
174
|
|
177
175
|
config do
|
178
176
|
transport SmartMessage::Transport.create(:memory)
|
179
|
-
serializer SmartMessage::Serializer::Json.new
|
180
177
|
end
|
181
178
|
end
|
182
179
|
```
|
@@ -201,7 +198,7 @@ order = OrderMessage.new(order_id: "123", amount: 99.99)
|
|
201
198
|
order.from("order-service").to("payment-service")
|
202
199
|
order.publish
|
203
200
|
# 1. Creates header with UUID, timestamp, addressing
|
204
|
-
# 2. Encodes message via serializer
|
201
|
+
# 2. Encodes message via transport's serializer
|
205
202
|
# 3. Sends via transport
|
206
203
|
# 4. Circuit breaker monitors for failures
|
207
204
|
```
|
@@ -210,7 +207,7 @@ order.publish
|
|
210
207
|
```ruby
|
211
208
|
# Transport receives serialized message
|
212
209
|
transport.receive(message_class, serialized_message)
|
213
|
-
# 1. Decodes message using
|
210
|
+
# 1. Decodes message using transport's serializer
|
214
211
|
# 2. Routes decoded message to dispatcher
|
215
212
|
# 3. Dispatcher checks DDQ for duplicates per handler
|
216
213
|
# 4. Applies message filters (from/to/broadcast)
|
@@ -271,7 +268,6 @@ SmartMessage supports configuration at both class and instance levels:
|
|
271
268
|
class PaymentMessage < SmartMessage::Base
|
272
269
|
config do
|
273
270
|
transport ProductionTransport.new
|
274
|
-
serializer SecureSerializer.new
|
275
271
|
end
|
276
272
|
end
|
277
273
|
|
@@ -459,7 +455,6 @@ Configuration uses method-based DSL:
|
|
459
455
|
```ruby
|
460
456
|
config do
|
461
457
|
transport MyTransport.new(option1: value1)
|
462
|
-
serializer MySerializer.new(option2: value2)
|
463
458
|
logger MyLogger.new(level: :debug)
|
464
459
|
end
|
465
460
|
```
|
@@ -20,7 +20,6 @@ class NotificationMessage < SmartMessage::Base
|
|
20
20
|
|
21
21
|
config do
|
22
22
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
23
|
-
serializer SmartMessage::Serializer::Json.new
|
24
23
|
end
|
25
24
|
|
26
25
|
def self.process(decoded_message)
|
@@ -87,7 +86,6 @@ class UserRegisteredEvent < SmartMessage::Base
|
|
87
86
|
|
88
87
|
config do
|
89
88
|
transport SmartMessage::Transport.create(:memory, auto_process: true)
|
90
|
-
serializer SmartMessage::Serializer::Json.new
|
91
89
|
end
|
92
90
|
|
93
91
|
def self.process(decoded_message)
|
@@ -152,7 +150,6 @@ class WelcomeEmailMessage < SmartMessage::Base
|
|
152
150
|
|
153
151
|
config do
|
154
152
|
transport SmartMessage::Transport.create(:stdout)
|
155
|
-
serializer SmartMessage::Serializer::Json.new
|
156
153
|
end
|
157
154
|
|
158
155
|
def self.process(decoded_message)
|
@@ -171,7 +168,6 @@ class AnalyticsMessage < SmartMessage::Base
|
|
171
168
|
|
172
169
|
config do
|
173
170
|
transport SmartMessage::Transport.create(:stdout)
|
174
|
-
serializer SmartMessage::Serializer::Json.new
|
175
171
|
end
|
176
172
|
|
177
173
|
def self.process(decoded_message)
|
@@ -209,7 +205,6 @@ class OrderCreatedMessage < SmartMessage::Base
|
|
209
205
|
|
210
206
|
config do
|
211
207
|
transport SmartMessage::Transport.create(:memory, auto_process: true)
|
212
|
-
serializer SmartMessage::Serializer::Json.new
|
213
208
|
end
|
214
209
|
|
215
210
|
def self.process(decoded_message)
|
@@ -252,7 +247,6 @@ class InventoryReservationMessage < SmartMessage::Base
|
|
252
247
|
|
253
248
|
config do
|
254
249
|
transport SmartMessage::Transport.create(:memory, auto_process: true)
|
255
|
-
serializer SmartMessage::Serializer::Json.new
|
256
250
|
end
|
257
251
|
|
258
252
|
def self.process(decoded_message)
|
@@ -289,7 +283,6 @@ class PaymentProcessingMessage < SmartMessage::Base
|
|
289
283
|
|
290
284
|
config do
|
291
285
|
transport SmartMessage::Transport.create(:memory, auto_process: true)
|
292
|
-
serializer SmartMessage::Serializer::Json.new
|
293
286
|
end
|
294
287
|
|
295
288
|
def self.process(decoded_message)
|
@@ -362,7 +355,6 @@ class LogMessage < SmartMessage::Base
|
|
362
355
|
|
363
356
|
config do
|
364
357
|
transport SmartMessage::Transport.create(:stdout, output: "application.log")
|
365
|
-
serializer SmartMessage::Serializer::Json.new
|
366
358
|
end
|
367
359
|
|
368
360
|
def self.process(decoded_message)
|
@@ -412,7 +404,6 @@ class MetricMessage < SmartMessage::Base
|
|
412
404
|
|
413
405
|
config do
|
414
406
|
transport SmartMessage::Transport.create(:memory, auto_process: true)
|
415
|
-
serializer SmartMessage::Serializer::Json.new
|
416
407
|
end
|
417
408
|
|
418
409
|
def self.process(decoded_message)
|
@@ -496,7 +487,6 @@ class MessageGateway < SmartMessage::Base
|
|
496
487
|
# Receive from one transport
|
497
488
|
config do
|
498
489
|
transport SmartMessage::Transport.create(:memory, auto_process: true)
|
499
|
-
serializer SmartMessage::Serializer::Json.new
|
500
490
|
end
|
501
491
|
|
502
492
|
def self.process(decoded_message)
|
@@ -621,7 +611,6 @@ class ResilientMessage < SmartMessage::Base
|
|
621
611
|
|
622
612
|
config do
|
623
613
|
transport SmartMessage::Transport.create(:memory, auto_process: true)
|
624
|
-
serializer SmartMessage::Serializer::Json.new
|
625
614
|
end
|
626
615
|
|
627
616
|
def self.process(decoded_message)
|
@@ -689,7 +678,6 @@ class DeadLetterMessage < SmartMessage::Base
|
|
689
678
|
|
690
679
|
config do
|
691
680
|
transport SmartMessage::Transport.create(:stdout, output: "dead_letter_queue.log")
|
692
|
-
serializer SmartMessage::Serializer::Json.new
|
693
681
|
end
|
694
682
|
|
695
683
|
def self.process(decoded_message)
|
@@ -92,7 +92,6 @@ class WelcomeMessage < SmartMessage::Base
|
|
92
92
|
# Configure the transport (where messages go)
|
93
93
|
config do
|
94
94
|
transport SmartMessage::Transport.create(:stdout, loopback: true)
|
95
|
-
serializer SmartMessage::Serializer::Json.new
|
96
95
|
end
|
97
96
|
|
98
97
|
# Define how to process received messages
|
@@ -213,12 +212,10 @@ transport SmartMessage::Transport.create(:memory, auto_process: true)
|
|
213
212
|
```
|
214
213
|
|
215
214
|
### Serializers
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
serializer SmartMessage::Serializer::Json.new
|
221
|
-
```
|
215
|
+
Transports handle their own serialization automatically:
|
216
|
+
- **MemoryTransport**: No serialization (objects passed directly)
|
217
|
+
- **StdoutTransport**: JSON serialization for readability
|
218
|
+
- **RedisTransport**: MessagePack (with JSON fallback) for efficiency
|
222
219
|
|
223
220
|
### Message Handlers
|
224
221
|
|
@@ -321,7 +318,6 @@ class NotificationMessage < SmartMessage::Base
|
|
321
318
|
|
322
319
|
config do
|
323
320
|
transport SmartMessage::Transport.create(:memory, auto_process: true)
|
324
|
-
serializer SmartMessage::Serializer::Json.new
|
325
321
|
end
|
326
322
|
|
327
323
|
def self.process(decoded_message)
|
@@ -364,7 +360,6 @@ class EventMessage < SmartMessage::Base
|
|
364
360
|
|
365
361
|
config do
|
366
362
|
transport SmartMessage::Transport.create(:stdout, output: 'events.log')
|
367
|
-
serializer SmartMessage::Serializer::Json.new
|
368
363
|
end
|
369
364
|
end
|
370
365
|
|
data/docs/index.md
CHANGED
@@ -31,13 +31,13 @@ Think of SmartMessage as ActiveRecord for messaging - just as ActiveRecord frees
|
|
31
31
|
|
32
32
|
### Transports
|
33
33
|
- [Transport Layer](reference/transports.md)
|
34
|
-
- [Redis
|
34
|
+
- [Redis Transport](transports/redis-transport.md)
|
35
35
|
- [Redis Transport Comparison](transports/redis-transport-comparison.md)
|
36
36
|
|
37
37
|
### Guides
|
38
|
-
- [
|
39
|
-
- [
|
40
|
-
- [
|
38
|
+
- [Examples & Use Cases](getting-started/examples.md)
|
39
|
+
- [Architecture Overview](core-concepts/architecture.md)
|
40
|
+
- [Transport Configuration](reference/transports.md)
|
41
41
|
|
42
42
|
### Reference
|
43
43
|
- [Serializers](reference/serializers.md)
|