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
@@ -53,7 +53,6 @@ module SmartMessage
|
|
53
53
|
# SmartMessage.configure do |config|
|
54
54
|
# config.logger = MyApp::Logger.new # Custom logger object
|
55
55
|
# config.transport = MyApp::Transport.new
|
56
|
-
# config.serializer = MyApp::Serializer.new
|
57
56
|
# end
|
58
57
|
#
|
59
58
|
# # Explicitly disable logging:
|
@@ -71,17 +70,16 @@ module SmartMessage
|
|
71
70
|
# class SpecialMessage < SmartMessage::Base
|
72
71
|
# config do
|
73
72
|
# logger MyApp::SpecialLogger.new # Override just the logger
|
74
|
-
# # transport
|
73
|
+
# # transport still uses global defaults
|
75
74
|
# end
|
76
75
|
# end
|
77
76
|
class Configuration
|
78
|
-
attr_accessor :transport, :
|
77
|
+
attr_accessor :transport, :log_level, :log_format, :log_include_source, :log_structured_data, :log_colorize, :log_options
|
79
78
|
attr_reader :logger
|
80
79
|
|
81
80
|
def initialize
|
82
81
|
@logger = nil
|
83
82
|
@transport = nil
|
84
|
-
@serializer = nil
|
85
83
|
@logger_explicitly_set_to_nil = false
|
86
84
|
@log_level = nil
|
87
85
|
@log_format = nil
|
@@ -101,7 +99,6 @@ module SmartMessage
|
|
101
99
|
def reset!
|
102
100
|
@logger = nil
|
103
101
|
@transport = nil
|
104
|
-
@serializer = nil
|
105
102
|
@logger_explicitly_set_to_nil = false
|
106
103
|
@log_level = nil
|
107
104
|
@log_format = nil
|
@@ -121,11 +118,6 @@ module SmartMessage
|
|
121
118
|
!@transport.nil?
|
122
119
|
end
|
123
120
|
|
124
|
-
# Check if serializer is configured
|
125
|
-
def serializer_configured?
|
126
|
-
!@serializer.nil?
|
127
|
-
end
|
128
|
-
|
129
121
|
# Get the configured logger or no logging
|
130
122
|
def default_logger
|
131
123
|
case @logger
|
@@ -156,11 +148,6 @@ module SmartMessage
|
|
156
148
|
@transport || framework_default_transport
|
157
149
|
end
|
158
150
|
|
159
|
-
# Get the configured serializer or framework default
|
160
|
-
def default_serializer
|
161
|
-
@serializer || framework_default_serializer
|
162
|
-
end
|
163
|
-
|
164
151
|
private
|
165
152
|
|
166
153
|
# Framework's built-in default logger (Lumberjack)
|
@@ -187,13 +174,5 @@ module SmartMessage
|
|
187
174
|
def framework_default_transport
|
188
175
|
SmartMessage::Transport::RedisTransport.new
|
189
176
|
end
|
190
|
-
|
191
|
-
# Framework's built-in default serializer (JSON)
|
192
|
-
def framework_default_serializer
|
193
|
-
SmartMessage::Serializer::Json.new
|
194
|
-
rescue
|
195
|
-
# Fallback if JSON serializer is not available
|
196
|
-
nil
|
197
|
-
end
|
198
177
|
end
|
199
178
|
end
|
@@ -48,7 +48,7 @@ module SmartMessage
|
|
48
48
|
# @param error_info [Hash] Error details including :error, :retry_count, :transport, etc.
|
49
49
|
def enqueue(message, error_info = {})
|
50
50
|
message_header = message._sm_header
|
51
|
-
message_payload = message.
|
51
|
+
message_payload = JSON.generate(message.to_hash)
|
52
52
|
|
53
53
|
entry = {
|
54
54
|
timestamp: Time.now.iso8601,
|
@@ -4,34 +4,8 @@
|
|
4
4
|
|
5
5
|
module SmartMessage
|
6
6
|
# Messaging module for SmartMessage::Base
|
7
|
-
# Handles message
|
7
|
+
# Handles message publishing operations
|
8
8
|
module Messaging
|
9
|
-
# SMELL: How does the transport know how to decode a message before
|
10
|
-
# it knows the message class? We need a wrapper around
|
11
|
-
# the entire message in a known serialization. That
|
12
|
-
# wrapper would contain two properties: _sm_header and
|
13
|
-
# _sm_payload
|
14
|
-
|
15
|
-
# NOTE: to publish a message it must first be encoded using a
|
16
|
-
# serializer. The receive a subscribed to message it must
|
17
|
-
# be decoded via a serializer from the transport to be processed.
|
18
|
-
def encode
|
19
|
-
raise Errors::SerializerNotConfigured if serializer_missing?
|
20
|
-
|
21
|
-
serializer.encode(self)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Convert message to hash with _sm_header and _sm_payload structure
|
25
|
-
# This is the foundation for wrapper architecture
|
26
|
-
def to_h
|
27
|
-
# Update header with serializer info before converting
|
28
|
-
_sm_header.serializer = serializer.class.to_s if serializer_configured?
|
29
|
-
|
30
|
-
{
|
31
|
-
:_sm_header => header_hash_with_symbols,
|
32
|
-
:_sm_payload => payload_hash_with_symbols
|
33
|
-
}
|
34
|
-
end
|
35
9
|
|
36
10
|
|
37
11
|
# NOTE: you publish instances; but, you subscribe/unsubscribe at
|
@@ -44,16 +18,12 @@ module SmartMessage
|
|
44
18
|
# Update header with current publication info
|
45
19
|
_sm_header.published_at = Time.now
|
46
20
|
_sm_header.publisher_pid = Process.pid
|
47
|
-
_sm_header.serializer = serializer.class.to_s if serializer_configured?
|
48
|
-
|
49
|
-
# Single-tier serialization: serialize entire message with designated serializer
|
50
|
-
serialized_message = encode
|
51
21
|
|
52
22
|
raise Errors::TransportNotConfigured if transport_missing?
|
53
23
|
|
54
|
-
# Transport
|
24
|
+
# Transport now handles serialization - just pass the message instance
|
55
25
|
(self.class.logger || SmartMessage::Logger.default).debug { "[SmartMessage::Messaging] About to call transport.publish" }
|
56
|
-
transport.publish(
|
26
|
+
transport.publish(self)
|
57
27
|
(self.class.logger || SmartMessage::Logger.default).debug { "[SmartMessage::Messaging] transport.publish completed" }
|
58
28
|
|
59
29
|
# Log the message publish
|
@@ -67,34 +37,5 @@ module SmartMessage
|
|
67
37
|
end
|
68
38
|
end # def publish
|
69
39
|
|
70
|
-
private
|
71
|
-
|
72
|
-
# Convert header to hash with symbol keys
|
73
|
-
def header_hash_with_symbols
|
74
|
-
_sm_header.to_hash.transform_keys(&:to_sym)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Extract all non-header properties into a hash with symbol keys
|
78
|
-
# Performs deep symbolization on nested structures
|
79
|
-
def payload_hash_with_symbols
|
80
|
-
self.class.properties.each_with_object({}) do |prop, hash|
|
81
|
-
next if prop == :_sm_header
|
82
|
-
hash[prop.to_sym] = deep_symbolize_keys(self[prop])
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# Recursively convert all string keys to symbols in nested hashes and arrays
|
87
|
-
def deep_symbolize_keys(obj)
|
88
|
-
case obj
|
89
|
-
when Hash
|
90
|
-
obj.each_with_object({}) do |(key, value), result|
|
91
|
-
result[key.to_sym] = deep_symbolize_keys(value)
|
92
|
-
end
|
93
|
-
when Array
|
94
|
-
obj.map { |item| deep_symbolize_keys(item) }
|
95
|
-
else
|
96
|
-
obj
|
97
|
-
end
|
98
|
-
end
|
99
40
|
end
|
100
41
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
module SmartMessage
|
6
6
|
# Plugin configuration module for SmartMessage::Base
|
7
|
-
# Handles transport
|
7
|
+
# Handles transport and logger configuration at both
|
8
8
|
# class and instance levels
|
9
9
|
module Plugins
|
10
10
|
def self.included(base)
|
@@ -12,7 +12,6 @@ module SmartMessage
|
|
12
12
|
base.class_eval do
|
13
13
|
# Class-level plugin storage
|
14
14
|
class_variable_set(:@@transport, nil) unless class_variable_defined?(:@@transport)
|
15
|
-
class_variable_set(:@@serializer, nil) unless class_variable_defined?(:@@serializer)
|
16
15
|
class_variable_set(:@@logger, nil) unless class_variable_defined?(:@@logger)
|
17
16
|
end
|
18
17
|
end
|
@@ -45,27 +44,6 @@ module SmartMessage
|
|
45
44
|
end
|
46
45
|
def reset_transport; @transport = nil; end
|
47
46
|
|
48
|
-
|
49
|
-
#########################################################
|
50
|
-
## instance-level serializer configuration
|
51
|
-
|
52
|
-
def serializer(klass_or_instance = nil)
|
53
|
-
if klass_or_instance.nil?
|
54
|
-
# Return instance serializer, class serializer, or global configuration
|
55
|
-
@serializer || self.class.class_variable_get(:@@serializer) || SmartMessage::Serializer.default
|
56
|
-
else
|
57
|
-
@serializer = klass_or_instance
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def serializer_configured?; !serializer_missing?; end
|
62
|
-
def serializer_missing?
|
63
|
-
# Check if serializer is explicitly configured (without fallback to defaults)
|
64
|
-
@serializer.nil? &&
|
65
|
-
(self.class.class_variable_get(:@@serializer) rescue nil).nil?
|
66
|
-
end
|
67
|
-
def reset_serializer; @serializer = nil; end
|
68
|
-
|
69
47
|
module ClassMethods
|
70
48
|
#########################################################
|
71
49
|
## class-level configuration
|
@@ -111,25 +89,6 @@ module SmartMessage
|
|
111
89
|
(class_variable_get(:@@logger) rescue nil).nil?
|
112
90
|
end
|
113
91
|
def reset_logger; class_variable_set(:@@logger, nil); end
|
114
|
-
|
115
|
-
#########################################################
|
116
|
-
## class-level serializer configuration
|
117
|
-
|
118
|
-
def serializer(klass_or_instance = nil)
|
119
|
-
if klass_or_instance.nil?
|
120
|
-
# Return class-level serializer or fall back to global configuration
|
121
|
-
class_variable_get(:@@serializer) || SmartMessage::Serializer.default
|
122
|
-
else
|
123
|
-
class_variable_set(:@@serializer, klass_or_instance)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def serializer_configured?; !serializer_missing?; end
|
128
|
-
def serializer_missing?
|
129
|
-
# Check if class-level serializer is explicitly configured (without fallback to defaults)
|
130
|
-
(class_variable_get(:@@serializer) rescue nil).nil?
|
131
|
-
end
|
132
|
-
def reset_serializer; class_variable_set(:@@serializer, nil); end
|
133
92
|
end
|
134
93
|
end
|
135
94
|
end
|
@@ -11,15 +11,17 @@ module SmartMessage
|
|
11
11
|
class Base
|
12
12
|
include BreakerMachines::DSL
|
13
13
|
|
14
|
-
attr_reader :options, :dispatcher
|
14
|
+
attr_reader :options, :dispatcher, :serializer
|
15
15
|
|
16
16
|
def initialize(**options)
|
17
17
|
@options = default_options.merge(options)
|
18
18
|
@dispatcher = options[:dispatcher] || SmartMessage::Dispatcher.new
|
19
|
+
@serializer = options[:serializer] || default_serializer
|
19
20
|
configure
|
20
21
|
configure_transport_circuit_breakers
|
21
22
|
|
22
23
|
logger.debug { "[SmartMessage::Transport::#{self.class.name.split('::').last}] Initialized with options: #{@options}" }
|
24
|
+
logger.debug { "[SmartMessage::Transport::#{self.class.name.split('::').last}] Using serializer: #{@serializer.class.name}" }
|
23
25
|
rescue => e
|
24
26
|
logger&.error { "[SmartMessage] Error in transport initialization: #{e.class.name} - #{e.message}" }
|
25
27
|
raise
|
@@ -43,10 +45,20 @@ module SmartMessage
|
|
43
45
|
{}
|
44
46
|
end
|
45
47
|
|
48
|
+
# Default serializer for this transport (override in subclasses)
|
49
|
+
def default_serializer
|
50
|
+
SmartMessage::Serializer::Json.new
|
51
|
+
end
|
52
|
+
|
46
53
|
# Publish a message with circuit breaker protection
|
47
|
-
# @param
|
48
|
-
|
49
|
-
|
54
|
+
# @param message [SmartMessage::Base] The message instance to publish
|
55
|
+
def publish(message)
|
56
|
+
# Extract routing info from message header
|
57
|
+
message_class = message._sm_header.message_class
|
58
|
+
|
59
|
+
# Serialize the entire message (flat structure with _sm_header)
|
60
|
+
serialized_message = encode_message(message)
|
61
|
+
|
50
62
|
circuit(:transport_publish).wrap do
|
51
63
|
do_publish(message_class, serialized_message)
|
52
64
|
end
|
@@ -58,7 +70,7 @@ module SmartMessage
|
|
58
70
|
raise unless e.is_a?(Hash) && e[:circuit_breaker]
|
59
71
|
|
60
72
|
# Handle circuit breaker fallback
|
61
|
-
handle_publish_fallback(e, message_class, serialized_message)
|
73
|
+
handle_publish_fallback(e, message._sm_header.message_class, serialized_message)
|
62
74
|
end
|
63
75
|
|
64
76
|
# Template method for actual publishing (implement in subclasses)
|
@@ -150,13 +162,32 @@ module SmartMessage
|
|
150
162
|
end
|
151
163
|
end
|
152
164
|
|
165
|
+
# Encode a message using the transport's serializer
|
166
|
+
# @param message [SmartMessage::Base] The message to encode
|
167
|
+
# @return [String] The serialized message
|
168
|
+
def encode_message(message)
|
169
|
+
# Update header with serializer info
|
170
|
+
message._sm_header.serializer = @serializer.class.to_s
|
171
|
+
|
172
|
+
# Serialize the entire message as a flat structure
|
173
|
+
@serializer.encode(message.to_hash)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Decode a message using the transport's serializer
|
177
|
+
# @param serialized_message [String] The serialized message
|
178
|
+
# @return [Hash] The decoded message data
|
179
|
+
def decode_message(serialized_message)
|
180
|
+
@serializer.decode(serialized_message)
|
181
|
+
end
|
182
|
+
|
153
183
|
# Receive and route a message (called by transport implementations)
|
154
184
|
# @param message_class [String] The message class name
|
155
185
|
# @param serialized_message [String] The serialized message content
|
156
186
|
protected
|
157
187
|
|
158
188
|
def receive(message_class, serialized_message)
|
159
|
-
# Decode the message using
|
189
|
+
# Decode the message using transport's serializer
|
190
|
+
decoded_data = decode_message(serialized_message)
|
160
191
|
|
161
192
|
# Add defensive check for message_class type
|
162
193
|
unless message_class.respond_to?(:constantize)
|
@@ -165,10 +196,13 @@ module SmartMessage
|
|
165
196
|
raise ArgumentError, "message_class must be a String, got #{message_class.class.name}"
|
166
197
|
end
|
167
198
|
|
199
|
+
# Reconstruct the message instance from flat structure
|
168
200
|
message_class_obj = message_class.constantize
|
169
|
-
|
201
|
+
# Convert string keys to symbols for keyword arguments
|
202
|
+
symbol_data = decoded_data.transform_keys(&:to_sym)
|
203
|
+
message = message_class_obj.new(**symbol_data)
|
170
204
|
|
171
|
-
@dispatcher.route(
|
205
|
+
@dispatcher.route(message)
|
172
206
|
rescue => e
|
173
207
|
logger.error { "[SmartMessage] Error in transport receive: #{e.class.name} - #{e.message}" }
|
174
208
|
logger.error { "[SmartMessage] message_class: #{message_class.inspect} (#{message_class.class.name})" }
|
@@ -16,30 +16,49 @@ module SmartMessage
|
|
16
16
|
}
|
17
17
|
end
|
18
18
|
|
19
|
+
# Memory transport doesn't need serialization
|
20
|
+
def default_serializer
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
19
24
|
def configure
|
20
25
|
@messages = []
|
21
26
|
@message_mutex = Mutex.new
|
22
27
|
end
|
23
28
|
|
24
|
-
#
|
29
|
+
# Implement do_publish for memory transport (no serialization needed)
|
25
30
|
def do_publish(message_class, serialized_message)
|
31
|
+
# For memory transport, serialized_message is actually the message object
|
32
|
+
message = serialized_message
|
33
|
+
|
26
34
|
@message_mutex.synchronize do
|
27
35
|
# Prevent memory overflow
|
28
36
|
@messages.shift if @messages.size >= @options[:max_messages]
|
29
37
|
|
38
|
+
# Store the actual message object, no serialization needed
|
30
39
|
@messages << {
|
31
40
|
message_class: message_class,
|
32
|
-
|
41
|
+
message: message.dup, # Store a copy to prevent mutation
|
33
42
|
published_at: Time.now
|
34
43
|
}
|
35
44
|
end
|
36
45
|
|
37
46
|
# Auto-process if enabled
|
38
47
|
if @options[:auto_process]
|
39
|
-
|
48
|
+
# Route directly without serialization
|
49
|
+
@dispatcher.route(message)
|
40
50
|
end
|
41
51
|
end
|
42
52
|
|
53
|
+
# Override encode_message to return the message object directly
|
54
|
+
def encode_message(message)
|
55
|
+
# Update header with serializer info (even though we don't serialize)
|
56
|
+
message._sm_header.serializer = 'none'
|
57
|
+
|
58
|
+
# Return the message object itself (no encoding needed)
|
59
|
+
message
|
60
|
+
end
|
61
|
+
|
43
62
|
# Get all stored messages
|
44
63
|
def all_messages
|
45
64
|
@message_mutex.synchronize { @messages.dup }
|
@@ -59,7 +78,7 @@ module SmartMessage
|
|
59
78
|
def process_all
|
60
79
|
messages_to_process = @message_mutex.synchronize { @messages.dup }
|
61
80
|
messages_to_process.each do |msg|
|
62
|
-
|
81
|
+
@dispatcher.route(msg[:message])
|
63
82
|
end
|
64
83
|
end
|
65
84
|
|
@@ -24,6 +24,17 @@ module SmartMessage
|
|
24
24
|
}
|
25
25
|
end
|
26
26
|
|
27
|
+
# Default to MessagePack for Redis (efficient binary format)
|
28
|
+
def default_serializer
|
29
|
+
# Try MessagePack first, fall back to JSON
|
30
|
+
begin
|
31
|
+
require 'smart_message/serializer/message_pack'
|
32
|
+
SmartMessage::Serializer::MessagePack.new
|
33
|
+
rescue LoadError
|
34
|
+
SmartMessage::Serializer::Json.new
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
27
38
|
def configure
|
28
39
|
@redis_pub = Redis.new(url: @options[:url], db: @options[:db])
|
29
40
|
@redis_sub = Redis.new(url: @options[:url], db: @options[:db])
|
@@ -54,7 +54,6 @@ module SmartMessage
|
|
54
54
|
register(:stdout, SmartMessage::Transport::StdoutTransport)
|
55
55
|
register(:memory, SmartMessage::Transport::MemoryTransport)
|
56
56
|
register(:redis, SmartMessage::Transport::RedisTransport)
|
57
|
-
register(:redis_queue, SmartMessage::Transport::RedisQueueTransport)
|
58
57
|
end
|
59
58
|
end
|
60
59
|
end
|
@@ -10,10 +10,16 @@ module SmartMessage
|
|
10
10
|
def default_options
|
11
11
|
{
|
12
12
|
loopback: false,
|
13
|
-
output: $stdout
|
13
|
+
output: $stdout,
|
14
|
+
format: :pretty # :pretty or :json
|
14
15
|
}
|
15
16
|
end
|
16
17
|
|
18
|
+
# Default to JSON for readability in STDOUT
|
19
|
+
def default_serializer
|
20
|
+
SmartMessage::Serializer::Json.new
|
21
|
+
end
|
22
|
+
|
17
23
|
def configure
|
18
24
|
@output = @options[:output].is_a?(String) ? File.open(@options[:output], 'w') : @options[:output]
|
19
25
|
end
|
@@ -27,7 +33,7 @@ module SmartMessage
|
|
27
33
|
@options[:loopback]
|
28
34
|
end
|
29
35
|
|
30
|
-
# Publish message to STDOUT
|
36
|
+
# Publish message to STDOUT
|
31
37
|
def do_publish(message_class, serialized_message)
|
32
38
|
logger.debug { "[SmartMessage::StdoutTransport] do_publish called" }
|
33
39
|
logger.debug { "[SmartMessage::StdoutTransport] message_class: #{message_class}" }
|
@@ -56,16 +62,28 @@ module SmartMessage
|
|
56
62
|
private
|
57
63
|
|
58
64
|
def format_message(message_class, serialized_message)
|
59
|
-
|
65
|
+
if @options[:format] == :json
|
66
|
+
# Output as JSON for machine parsing
|
67
|
+
{
|
68
|
+
transport: 'stdout',
|
69
|
+
message_class: message_class,
|
70
|
+
serialized_message: serialized_message,
|
71
|
+
timestamp: Time.now.iso8601
|
72
|
+
}.to_json
|
73
|
+
else
|
74
|
+
# Pretty format for human reading
|
75
|
+
<<~MESSAGE
|
60
76
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
77
|
+
===================================================
|
78
|
+
== SmartMessage Published via STDOUT Transport
|
79
|
+
== Message Class: #{message_class}
|
80
|
+
== Serializer: #{@serializer.class.name}
|
81
|
+
== Serialized Message:
|
82
|
+
#{serialized_message}
|
83
|
+
===================================================
|
67
84
|
|
68
|
-
|
85
|
+
MESSAGE
|
86
|
+
end
|
69
87
|
end
|
70
88
|
end
|
71
89
|
end
|
@@ -7,7 +7,6 @@ require_relative 'transport/registry'
|
|
7
7
|
require_relative 'transport/stdout_transport'
|
8
8
|
require_relative 'transport/memory_transport'
|
9
9
|
require_relative 'transport/redis_transport'
|
10
|
-
require_relative 'transport/redis_queue_transport'
|
11
10
|
|
12
11
|
module SmartMessage
|
13
12
|
module Transport
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_message
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dewayne VanHoozer
|
@@ -311,9 +311,6 @@ files:
|
|
311
311
|
- docs/development/troubleshooting.md
|
312
312
|
- docs/getting-started/examples.md
|
313
313
|
- docs/getting-started/quick-start.md
|
314
|
-
- docs/guides/redis-queue-getting-started.md
|
315
|
-
- docs/guides/redis-queue-patterns.md
|
316
|
-
- docs/guides/redis-queue-production.md
|
317
314
|
- docs/index.md
|
318
315
|
- docs/reference/dead-letter-queue.md
|
319
316
|
- docs/reference/logging.md
|
@@ -322,8 +319,6 @@ files:
|
|
322
319
|
- docs/reference/serializers.md
|
323
320
|
- docs/reference/transports.md
|
324
321
|
- docs/transports/memory-transport.md
|
325
|
-
- docs/transports/redis-enhanced-transport.md
|
326
|
-
- docs/transports/redis-queue-transport.md
|
327
322
|
- docs/transports/redis-transport-comparison.md
|
328
323
|
- docs/transports/redis-transport.md
|
329
324
|
- examples/.gitignore
|
@@ -399,25 +394,6 @@ files:
|
|
399
394
|
- examples/redis/redis_transport_architecture.svg
|
400
395
|
- examples/redis/smart_home_iot_dataflow.md
|
401
396
|
- examples/redis/smart_home_system_architecture.svg
|
402
|
-
- examples/redis_enhanced/README.md
|
403
|
-
- examples/redis_enhanced/enhanced_01_basic_patterns.rb
|
404
|
-
- examples/redis_enhanced/enhanced_02_fluent_api.rb
|
405
|
-
- examples/redis_enhanced/enhanced_03_dual_publishing.rb
|
406
|
-
- examples/redis_enhanced/enhanced_04_advanced_routing.rb
|
407
|
-
- examples/redis_queue/01_basic_messaging.rb
|
408
|
-
- examples/redis_queue/01_comprehensive_examples.rb
|
409
|
-
- examples/redis_queue/02_pattern_routing.rb
|
410
|
-
- examples/redis_queue/03_fluent_api.rb
|
411
|
-
- examples/redis_queue/04_load_balancing.rb
|
412
|
-
- examples/redis_queue/05_microservices.rb
|
413
|
-
- examples/redis_queue/06_emergency_alerts.rb
|
414
|
-
- examples/redis_queue/07_queue_management.rb
|
415
|
-
- examples/redis_queue/README.md
|
416
|
-
- examples/redis_queue/enhanced_01_basic_patterns.rb
|
417
|
-
- examples/redis_queue/enhanced_02_fluent_api.rb
|
418
|
-
- examples/redis_queue/enhanced_03_dual_publishing.rb
|
419
|
-
- examples/redis_queue/enhanced_04_advanced_routing.rb
|
420
|
-
- examples/redis_queue/redis_queue_architecture.svg
|
421
397
|
- ideas/README.md
|
422
398
|
- ideas/agents.md
|
423
399
|
- ideas/database_transport.md
|
@@ -463,8 +439,6 @@ files:
|
|
463
439
|
- lib/smart_message/transport.rb
|
464
440
|
- lib/smart_message/transport/base.rb
|
465
441
|
- lib/smart_message/transport/memory_transport.rb
|
466
|
-
- lib/smart_message/transport/redis_enhanced_transport.rb
|
467
|
-
- lib/smart_message/transport/redis_queue_transport.rb
|
468
442
|
- lib/smart_message/transport/redis_transport.rb
|
469
443
|
- lib/smart_message/transport/registry.rb
|
470
444
|
- lib/smart_message/transport/stdout_transport.rb
|
@@ -499,7 +473,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
499
473
|
- !ruby/object:Gem::Version
|
500
474
|
version: '0'
|
501
475
|
requirements: []
|
502
|
-
rubygems_version: 3.7.
|
476
|
+
rubygems_version: 3.7.2
|
503
477
|
specification_version: 4
|
504
478
|
summary: An abstraction to protect message content from the backend delivery transport.
|
505
479
|
test_files: []
|