smart_message 0.0.1

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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.envrc +3 -0
  3. data/.gitignore +8 -0
  4. data/.travis.yml +7 -0
  5. data/CHANGELOG.md +100 -0
  6. data/COMMITS.md +196 -0
  7. data/Gemfile +6 -0
  8. data/Gemfile.lock +71 -0
  9. data/README.md +303 -0
  10. data/Rakefile +10 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/docs/README.md +52 -0
  14. data/docs/architecture.md +370 -0
  15. data/docs/dispatcher.md +593 -0
  16. data/docs/examples.md +808 -0
  17. data/docs/getting-started.md +235 -0
  18. data/docs/ideas_to_think_about.md +329 -0
  19. data/docs/serializers.md +575 -0
  20. data/docs/transports.md +501 -0
  21. data/docs/troubleshooting.md +582 -0
  22. data/examples/01_point_to_point_orders.rb +200 -0
  23. data/examples/02_publish_subscribe_events.rb +364 -0
  24. data/examples/03_many_to_many_chat.rb +608 -0
  25. data/examples/README.md +335 -0
  26. data/examples/tmux_chat/README.md +283 -0
  27. data/examples/tmux_chat/bot_agent.rb +272 -0
  28. data/examples/tmux_chat/human_agent.rb +197 -0
  29. data/examples/tmux_chat/room_monitor.rb +158 -0
  30. data/examples/tmux_chat/shared_chat_system.rb +295 -0
  31. data/examples/tmux_chat/start_chat_demo.sh +190 -0
  32. data/examples/tmux_chat/stop_chat_demo.sh +22 -0
  33. data/lib/simple_stats.rb +57 -0
  34. data/lib/smart_message/base.rb +284 -0
  35. data/lib/smart_message/dispatcher/.keep +0 -0
  36. data/lib/smart_message/dispatcher.rb +146 -0
  37. data/lib/smart_message/errors.rb +29 -0
  38. data/lib/smart_message/header.rb +20 -0
  39. data/lib/smart_message/logger/base.rb +8 -0
  40. data/lib/smart_message/logger.rb +7 -0
  41. data/lib/smart_message/serializer/base.rb +23 -0
  42. data/lib/smart_message/serializer/json.rb +22 -0
  43. data/lib/smart_message/serializer.rb +10 -0
  44. data/lib/smart_message/transport/base.rb +85 -0
  45. data/lib/smart_message/transport/memory_transport.rb +69 -0
  46. data/lib/smart_message/transport/registry.rb +59 -0
  47. data/lib/smart_message/transport/stdout_transport.rb +62 -0
  48. data/lib/smart_message/transport.rb +41 -0
  49. data/lib/smart_message/version.rb +7 -0
  50. data/lib/smart_message/wrapper.rb +43 -0
  51. data/lib/smart_message.rb +54 -0
  52. data/smart_message.gemspec +53 -0
  53. metadata +252 -0
data/README.md ADDED
@@ -0,0 +1,303 @@
1
+ # SmartMessage
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/smart_message.svg)](https://badge.fury.io/rb/smart_message)
4
+ [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.0.0-ruby.svg)](https://www.ruby-lang.org/en/)
5
+
6
+ SmartMessage is a message abstraction framework that decouples business logic from message transports and serialization formats. Much like ActiveRecord abstracts models from database implementations, SmartMessage abstracts messages from their backend transport and serialization mechanisms.
7
+
8
+ ## Features
9
+
10
+ - **Transport Abstraction**: Plugin architecture supporting multiple message transports (RabbitMQ, Kafka, etc.)
11
+ - **Serialization Flexibility**: Pluggable serialization formats (JSON, MessagePack, etc.)
12
+ - **Dual-Level Configuration**: Class and instance-level plugin overrides for gateway patterns
13
+ - **Concurrent Processing**: Thread-safe message routing using `Concurrent::CachedThreadPool`
14
+ - **Built-in Statistics**: Message processing metrics and monitoring
15
+ - **Development Tools**: STDOUT and in-memory transports for testing
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'smart_message'
23
+ ```
24
+
25
+ And then execute:
26
+
27
+ $ bundle install
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install smart_message
32
+
33
+ ## Quick Start
34
+
35
+ ### 1. Define a Message Class
36
+
37
+ ```ruby
38
+ class OrderMessage < SmartMessage::Base
39
+ property :order_id
40
+ property :customer_id
41
+ property :amount
42
+ property :items
43
+
44
+ # Configure transport and serializer at class level
45
+ config do
46
+ transport SmartMessage::Transport.create(:stdout, loopback: true)
47
+ serializer SmartMessage::Serializer::JSON.new
48
+ end
49
+
50
+ # Business logic for processing received messages
51
+ def self.process(message_header, message_payload)
52
+ # Decode the message
53
+ order_data = JSON.parse(message_payload)
54
+ order = new(order_data)
55
+
56
+ # Process the order
57
+ puts "Processing order #{order.order_id} for customer #{order.customer_id}"
58
+ puts "Amount: $#{order.amount}"
59
+
60
+ # Your business logic here
61
+ process_order(order)
62
+ end
63
+
64
+ private
65
+
66
+ def self.process_order(order)
67
+ # Implementation specific to your domain
68
+ end
69
+ end
70
+ ```
71
+
72
+ ### 2. Publish Messages
73
+
74
+ ```ruby
75
+ # Create and publish a message
76
+ order = OrderMessage.new(
77
+ order_id: "ORD-123",
78
+ customer_id: "CUST-456",
79
+ amount: 99.99,
80
+ items: ["Widget A", "Widget B"]
81
+ )
82
+
83
+ order.publish
84
+ ```
85
+
86
+ ### 3. Subscribe to Messages
87
+
88
+ ```ruby
89
+ # Subscribe to process incoming OrderMessage instances
90
+ OrderMessage.subscribe
91
+
92
+ # Or specify a custom processing method
93
+ OrderMessage.subscribe("OrderMessage.custom_processor")
94
+ ```
95
+
96
+ ## Architecture
97
+
98
+ ### Core Components
99
+
100
+ #### SmartMessage::Base
101
+ The foundation class that all messages inherit from. Built on `Hashie::Dash` with extensions for:
102
+ - Property management and coercion
103
+ - Multi-level plugin configuration
104
+ - Message lifecycle management
105
+ - Automatic header generation (UUID, timestamps, process tracking)
106
+
107
+ #### Transport Layer
108
+ Pluggable message delivery system with built-in implementations:
109
+
110
+ - **StdoutTransport**: Development and testing transport
111
+ - **MemoryTransport**: In-memory queuing for testing
112
+ - **Custom Transports**: Implement `SmartMessage::Transport::Base`
113
+
114
+ #### Serializer System
115
+ Pluggable message encoding/decoding:
116
+
117
+ - **JSON Serializer**: Built-in JSON support
118
+ - **Custom Serializers**: Implement `SmartMessage::Serializer::Base`
119
+
120
+ #### Dispatcher
121
+ Concurrent message routing engine that:
122
+ - Uses thread pools for async processing
123
+ - Routes messages to subscribed handlers
124
+ - Provides processing statistics
125
+ - Handles graceful shutdown
126
+
127
+ ### Plugin Architecture
128
+
129
+ SmartMessage supports two levels of plugin configuration:
130
+
131
+ ```ruby
132
+ # Class-level configuration (default for all instances)
133
+ class MyMessage < SmartMessage::Base
134
+ config do
135
+ transport MyTransport.new
136
+ serializer MySerializer.new
137
+ logger MyLogger.new
138
+ end
139
+ end
140
+
141
+ # Instance-level configuration (overrides class defaults)
142
+ message = MyMessage.new
143
+ message.config do
144
+ transport DifferentTransport.new # Override for this instance
145
+ end
146
+ ```
147
+
148
+ This enables gateway patterns where messages can be received from one transport/serializer and republished to another.
149
+
150
+ ## Transport Implementations
151
+
152
+ ### STDOUT Transport (Development)
153
+
154
+ ```ruby
155
+ # Basic STDOUT output
156
+ transport = SmartMessage::Transport.create(:stdout)
157
+
158
+ # With loopback for testing subscriptions
159
+ transport = SmartMessage::Transport.create(:stdout, loopback: true)
160
+
161
+ # Output to file
162
+ transport = SmartMessage::Transport.create(:stdout, output: "messages.log")
163
+ ```
164
+
165
+ ### Memory Transport (Testing)
166
+
167
+ ```ruby
168
+ # Auto-process messages as they're published
169
+ transport = SmartMessage::Transport.create(:memory, auto_process: true)
170
+
171
+ # Store messages without processing
172
+ transport = SmartMessage::Transport.create(:memory, auto_process: false)
173
+
174
+ # Check stored messages
175
+ puts transport.message_count
176
+ puts transport.all_messages
177
+ transport.process_all # Process all pending messages
178
+ ```
179
+
180
+ ### Custom Transport
181
+
182
+ ```ruby
183
+ class RedisTransport < SmartMessage::Transport::Base
184
+ def default_options
185
+ { redis_url: "redis://localhost:6379" }
186
+ end
187
+
188
+ def configure
189
+ @redis = Redis.new(url: @options[:redis_url])
190
+ end
191
+
192
+ def publish(message_header, message_payload)
193
+ channel = message_header.message_class
194
+ @redis.publish(channel, message_payload)
195
+ end
196
+
197
+ def subscribe(message_class, process_method)
198
+ super
199
+ # Set up Redis subscription for message_class
200
+ end
201
+ end
202
+
203
+ # Register the transport
204
+ SmartMessage::Transport.register(:redis, RedisTransport)
205
+
206
+ # Use the transport
207
+ MyMessage.config do
208
+ transport SmartMessage::Transport.create(:redis, redis_url: "redis://prod:6379")
209
+ end
210
+ ```
211
+
212
+ ## Message Lifecycle
213
+
214
+ 1. **Definition**: Create message class inheriting from `SmartMessage::Base`
215
+ 2. **Configuration**: Set transport, serializer, and logger plugins
216
+ 3. **Publishing**: Message instance is encoded and sent through transport
217
+ 4. **Subscription**: Message classes register with dispatcher for processing
218
+ 5. **Processing**: Received messages are decoded and `process` method is called
219
+
220
+ ## Advanced Usage
221
+
222
+ ### Statistics and Monitoring
223
+
224
+ SmartMessage includes built-in statistics collection:
225
+
226
+ ```ruby
227
+ # Access global statistics
228
+ puts SS.stat # Shows all collected statistics
229
+
230
+ # Get specific counts
231
+ publish_count = SS.get("MyMessage", "publish")
232
+ process_count = SS.get("MyMessage", "MyMessage.process", "routed")
233
+
234
+ # Reset statistics
235
+ SS.reset # Clear all stats
236
+ SS.reset("MyMessage", "publish") # Reset specific stat
237
+ ```
238
+
239
+ ### Dispatcher Status
240
+
241
+ ```ruby
242
+ dispatcher = SmartMessage::Dispatcher.new
243
+
244
+ # Check thread pool status
245
+ status = dispatcher.status
246
+ puts "Running: #{status[:running]}"
247
+ puts "Queue length: #{status[:queue_length]}"
248
+ puts "Completed tasks: #{status[:completed_task_count]}"
249
+
250
+ # Check subscriptions
251
+ puts dispatcher.subscribers
252
+ ```
253
+
254
+ ### Message Properties and Headers
255
+
256
+ ```ruby
257
+ class MyMessage < SmartMessage::Base
258
+ property :user_id
259
+ property :action
260
+ property :timestamp, default: -> { Time.now }
261
+ end
262
+
263
+ message = MyMessage.new(user_id: 123, action: "login")
264
+
265
+ # Access message properties
266
+ puts message.user_id
267
+ puts message.fields # Returns Set of property names (excluding internal _sm_ properties)
268
+
269
+ # Access message header
270
+ puts message._sm_header.uuid
271
+ puts message._sm_header.message_class
272
+ puts message._sm_header.published_at
273
+ puts message._sm_header.publisher_pid
274
+ ```
275
+
276
+ ## Development
277
+
278
+ After checking out the repo, run:
279
+
280
+ ```bash
281
+ bin/setup # Install dependencies
282
+ bin/console # Start interactive console
283
+ rake test # Run test suite
284
+ ```
285
+
286
+ ### Testing
287
+
288
+ SmartMessage uses Minitest with Shoulda for testing:
289
+
290
+ ```bash
291
+ rake test # Run all tests
292
+ ruby -Ilib:test test/base_test.rb # Run specific test file
293
+ ```
294
+
295
+ Test output and debug information is logged to `test.log`.
296
+
297
+ ## Contributing
298
+
299
+ Bug reports and pull requests are welcome on GitHub at https://github.com/MadBomber/smart_message.
300
+
301
+ ## License
302
+
303
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "smart_message"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/docs/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # SmartMessage Documentation
2
+
3
+ Welcome to the comprehensive documentation for SmartMessage, a Ruby gem that abstracts messages from backend transport systems.
4
+
5
+ ## Table of Contents
6
+
7
+ ### Getting Started
8
+ - [Installation & Quick Start](getting-started.md)
9
+ - [Basic Usage Examples](examples.md)
10
+
11
+ ### Core Concepts
12
+ - [Architecture Overview](architecture.md)
13
+ - [Message Lifecycle](message-lifecycle.md)
14
+ - [Plugin System](plugin-system.md)
15
+
16
+ ### Components
17
+ - [SmartMessage::Base](base.md)
18
+ - [Transport Layer](transports.md)
19
+ - [Serializers](serializers.md)
20
+ - [Dispatcher & Routing](dispatcher.md)
21
+ - [Message Headers](headers.md)
22
+
23
+ ### Advanced Topics
24
+ - [Custom Transports](custom-transports.md)
25
+ - [Custom Serializers](custom-serializers.md)
26
+ - [Gateway Patterns](gateway-patterns.md)
27
+ - [Statistics & Monitoring](monitoring.md)
28
+ - [Thread Safety](thread-safety.md)
29
+
30
+ ### Development
31
+ - [Testing Guide](testing.md)
32
+ - [Contributing](contributing.md)
33
+ - [Troubleshooting](troubleshooting.md)
34
+
35
+ ### Reference
36
+ - [API Reference](api-reference.md)
37
+ - [Configuration Options](configuration.md)
38
+ - [Error Handling](error-handling.md)
39
+
40
+ ## Quick Navigation
41
+
42
+ - **New to SmartMessage?** Start with [Getting Started](getting-started.md)
43
+ - **Need examples?** Check out [Examples](examples.md)
44
+ - **Understanding the architecture?** Read [Architecture Overview](architecture.md)
45
+ - **Building custom components?** See [Custom Transports](custom-transports.md) and [Custom Serializers](custom-serializers.md)
46
+ - **Having issues?** Visit [Troubleshooting](troubleshooting.md)
47
+
48
+ ## Version
49
+
50
+ This documentation is for SmartMessage v0.0.1.
51
+
52
+ For older versions, please check the git tags and corresponding documentation.