smart_message 0.0.2 → 0.0.4

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.
data/docs/transports.md CHANGED
@@ -125,6 +125,194 @@ messages.each do |msg|
125
125
  end
126
126
  ```
127
127
 
128
+ ### Redis Transport
129
+
130
+ Production-ready Redis pub/sub transport for distributed messaging.
131
+
132
+ **Features:**
133
+ - Redis pub/sub messaging
134
+ - Automatic channel management using message class names
135
+ - Thread-safe subscriber management
136
+ - Connection resilience with automatic reconnection
137
+ - Configurable connection parameters
138
+ - Background message subscription threads
139
+
140
+ **Usage:**
141
+
142
+ ```ruby
143
+ # Basic Redis configuration
144
+ transport = SmartMessage::Transport.create(:redis,
145
+ url: 'redis://localhost:6379',
146
+ db: 0
147
+ )
148
+
149
+ # Production configuration with custom options
150
+ transport = SmartMessage::Transport.create(:redis,
151
+ url: 'redis://prod-redis:6379',
152
+ db: 1,
153
+ auto_subscribe: true,
154
+ reconnect_attempts: 5,
155
+ reconnect_delay: 2
156
+ )
157
+
158
+ # Configure in message class
159
+ class OrderMessage < SmartMessage::Base
160
+ property :order_id
161
+ property :customer_id
162
+ property :amount
163
+
164
+ config do
165
+ transport SmartMessage::Transport.create(:redis,
166
+ url: 'redis://localhost:6379',
167
+ db: 1
168
+ )
169
+ serializer SmartMessage::Serializer::JSON.new
170
+ end
171
+
172
+ def self.process(message_header, message_payload)
173
+ order_data = JSON.parse(message_payload)
174
+ order = new(order_data)
175
+ puts "Processing order #{order.order_id} for $#{order.amount}"
176
+ # Your business logic here
177
+ end
178
+ end
179
+
180
+ # Subscribe to messages (creates Redis subscription to "OrderMessage" channel)
181
+ OrderMessage.subscribe
182
+
183
+ # Publish messages (publishes to "OrderMessage" Redis channel)
184
+ order = OrderMessage.new(
185
+ order_id: "ORD-123",
186
+ customer_id: "CUST-456",
187
+ amount: 99.99
188
+ )
189
+ order.publish
190
+ ```
191
+
192
+ **Options:**
193
+ - `url` (String): Redis connection URL (default: 'redis://localhost:6379')
194
+ - `db` (Integer): Redis database number (default: 0)
195
+ - `auto_subscribe` (Boolean): Automatically start subscriber thread (default: true)
196
+ - `reconnect_attempts` (Integer): Number of reconnection attempts (default: 5)
197
+ - `reconnect_delay` (Integer): Delay between reconnection attempts in seconds (default: 1)
198
+ - `debug` (Boolean): Enable debug output (default: false)
199
+
200
+ **Channel Naming:**
201
+
202
+ The Redis transport uses the message class name as the Redis channel name. This provides automatic routing:
203
+
204
+ ```ruby
205
+ class UserMessage < SmartMessage::Base
206
+ # Messages published to/from Redis channel "UserMessage"
207
+ end
208
+
209
+ class AdminMessage < SmartMessage::Base
210
+ # Messages published to/from Redis channel "AdminMessage"
211
+ end
212
+
213
+ class OrderProcessing::PaymentMessage < SmartMessage::Base
214
+ # Messages published to/from Redis channel "OrderProcessing::PaymentMessage"
215
+ end
216
+ ```
217
+
218
+ **Connection Management:**
219
+
220
+ ```ruby
221
+ transport = SmartMessage::Transport.create(:redis, url: 'redis://localhost:6379')
222
+
223
+ # Check connection status
224
+ puts transport.connected? # => true/false
225
+
226
+ # Manual connection management
227
+ transport.connect
228
+ transport.disconnect
229
+
230
+ # The transport automatically reconnects on connection failures
231
+ ```
232
+
233
+ **Multi-Message Type Support:**
234
+
235
+ ```ruby
236
+ # Different message types can share the same Redis transport
237
+ redis_transport = SmartMessage::Transport.create(:redis,
238
+ url: 'redis://localhost:6379',
239
+ auto_subscribe: true
240
+ )
241
+
242
+ # Configure multiple message classes to use the same transport
243
+ [OrderMessage, PaymentMessage, ShippingMessage].each do |msg_class|
244
+ msg_class.config do
245
+ transport redis_transport
246
+ serializer SmartMessage::Serializer::JSON.new
247
+ end
248
+
249
+ # Subscribe to each message type (creates separate Redis subscriptions)
250
+ msg_class.subscribe
251
+ end
252
+
253
+ # Publishing to any message type routes to its specific Redis channel
254
+ OrderMessage.new(order_id: "123").publish # -> "OrderMessage" channel
255
+ PaymentMessage.new(amount: 50.0).publish # -> "PaymentMessage" channel
256
+ ShippingMessage.new(tracking: "ABC").publish # -> "ShippingMessage" channel
257
+ ```
258
+
259
+ **Error Handling and Resilience:**
260
+
261
+ The Redis transport includes built-in error handling:
262
+
263
+ ```ruby
264
+ # Automatic reconnection on connection failures
265
+ transport = SmartMessage::Transport.create(:redis,
266
+ url: 'redis://localhost:6379',
267
+ reconnect_attempts: 5, # Try 5 times to reconnect
268
+ reconnect_delay: 2 # Wait 2 seconds between attempts
269
+ )
270
+
271
+ # Connection failures during publishing will trigger automatic retry
272
+ # If all reconnection attempts fail, the original error is raised
273
+ ```
274
+
275
+ **Production Deployment:**
276
+
277
+ ```ruby
278
+ # Production Redis configuration
279
+ class ProductionMessage < SmartMessage::Base
280
+ config do
281
+ transport SmartMessage::Transport.create(:redis,
282
+ url: ENV['REDIS_URL'] || 'redis://localhost:6379',
283
+ db: ENV['REDIS_DB']&.to_i || 0,
284
+ auto_subscribe: true,
285
+ reconnect_attempts: 10,
286
+ reconnect_delay: 5
287
+ )
288
+ serializer SmartMessage::Serializer::JSON.new
289
+ logger Logger.new(STDOUT)
290
+ end
291
+ end
292
+ ```
293
+
294
+ **Testing with Redis:**
295
+
296
+ ```ruby
297
+ # Test configuration (using separate Redis database)
298
+ class TestMessage < SmartMessage::Base
299
+ config do
300
+ transport SmartMessage::Transport.create(:redis,
301
+ url: 'redis://localhost:6379',
302
+ db: 15, # Use separate database for tests
303
+ auto_subscribe: true
304
+ )
305
+ serializer SmartMessage::Serializer::JSON.new
306
+ end
307
+ end
308
+
309
+ # In your test setup
310
+ def setup
311
+ # Clear test database
312
+ Redis.new(url: 'redis://localhost:6379', db: 15).flushdb
313
+ end
314
+ ```
315
+
128
316
  ## Transport Interface
129
317
 
130
318
  All transports must implement the `SmartMessage::Transport::Base` interface:
@@ -188,19 +376,24 @@ transport.receive(message_header, message_payload) # protected method
188
376
  Register custom transports for easy creation:
189
377
 
190
378
  ```ruby
191
- # Register a transport class
192
- SmartMessage::Transport.register(:redis, RedisTransport)
379
+ # Register custom transport classes
193
380
  SmartMessage::Transport.register(:kafka, KafkaTransport)
381
+ SmartMessage::Transport.register(:webhook, WebhookTransport)
194
382
 
195
- # List all registered transports
383
+ # List all registered transports (includes built-ins)
196
384
  puts SmartMessage::Transport.available
197
- # => [:stdout, :memory, :redis, :kafka]
385
+ # => [:stdout, :memory, :redis, :kafka, :webhook]
198
386
 
199
- # Create instances
387
+ # Create instances of built-in transports
200
388
  redis_transport = SmartMessage::Transport.create(:redis,
201
389
  url: "redis://localhost:6379"
202
390
  )
203
391
 
392
+ memory_transport = SmartMessage::Transport.create(:memory,
393
+ auto_process: true
394
+ )
395
+
396
+ # Create instances of custom transports
204
397
  kafka_transport = SmartMessage::Transport.create(:kafka,
205
398
  servers: ["localhost:9092"]
206
399
  )
@@ -311,12 +504,13 @@ SmartMessage::Transport.create(:memory,
311
504
  max_messages: 1000
312
505
  )
313
506
 
314
- # Hypothetical Redis specific
507
+ # Redis specific
315
508
  SmartMessage::Transport.create(:redis,
316
509
  url: "redis://localhost:6379",
317
510
  db: 1,
318
- namespace: "messages",
319
- ttl: 3600
511
+ auto_subscribe: true,
512
+ reconnect_attempts: 5,
513
+ reconnect_delay: 2
320
514
  )
321
515
  ```
322
516
 
@@ -0,0 +1,2 @@
1
+ /log/
2
+ *.log