EventSystem
A flexible, agnostic event system for Ruby applications. EventSystem provides event-driven architecture with pluggable storage backends, visualization tools, and comprehensive logging. Perfect for building decoupled, maintainable applications.
Features
- 🎯 Event-Driven Architecture: Clean separation of concerns through events
- 💾 Pluggable Storage: Memory, file, and extensible storage backends
- 📊 Visualization Tools: HTML timeline generation for debugging
- 🔧 Flexible Configuration: Easy setup and customization
- 🚀 High Performance: Optimized for both development and production
- 📝 Comprehensive Logging: Built-in logging with configurable levels
- 🔍 Event Querying: Filter and search events by type, time, and more
- 🎨 Modern API: Clean, intuitive Ruby API
Installation
Add this line to your application's Gemfile:
gem 'event_system'And then execute:
bundle installOr install it directly:
gem install event_systemQuick Start
Basic Usage
require 'event_system'
# Create an event manager
manager = EventSystem.create_manager
# Create and publish an event
manager.publish_event(:user_created, self, { user_id: 123, name: "John Doe" })
# Subscribe to events
class UserNotifier
include EventSystem::EventSubscriber
def handle_event(event)
puts "User event: #{event.type} - #{event.data}"
end
end
notifier = UserNotifier.new
manager.subscribe(:user_created, notifier)Configuration
# Configure with file storage
config = {
storage_type: :file,
storage_options: { directory: "logs/events" },
session_id: "my_app_session"
}
manager = EventSystem.create_manager(config)
# Or use memory storage for testing
manager = EventSystem.create_manager(storage_type: :memory)Usage
Creating Events
# Create an event manually
event = EventSystem.create_event(:order_placed, self, {
order_id: 456,
customer_id: 789,
amount: 99.99
})
# Publish the event
manager.publish(event)Event Subscribers
class OrderProcessor
include EventSystem::EventSubscriber
def handle_event(event)
case event.type
when 'order_placed'
process_order(event.data)
when 'payment_received'
fulfill_order(event.data)
end
end
private
def process_order(data)
puts "Processing order #{data[:order_id]}"
end
def fulfill_order(data)
puts "Fulfilling order #{data[:order_id]}"
end
end
# Subscribe to specific events
processor = OrderProcessor.new
manager.subscribe(:order_placed, processor)
manager.subscribe(:payment_received, processor)
# Subscribe to all events
manager.subscribe_all(processor)Event Querying
# Query events by type
orders = manager.query_events(type: 'order_placed')
# Query events by time range
recent_events = manager.query_events(
start_time: 1.hour.ago,
end_time: Time.now
)
# Query with limit
last_10_events = manager.query_events(limit: 10)
# Query from specific session
session_events = manager.query_events(session_id: 'session_123')Storage Backends
Memory Storage (Default)
# Perfect for testing and development
manager = EventSystem.create_manager(storage_type: :memory)
# Switch sessions
manager.switch_session('test_session_1')
manager.publish_event(:test_event, self, { data: 'test' })
# Create new session
new_session = manager.create_session('my_new_session')File Storage
# Persistent storage to disk
config = {
storage_type: :file,
storage_options: { directory: 'event_logs' }
}
manager = EventSystem.create_manager(config)
# Events are automatically saved to JSONL files
manager.publish_event(:user_action, self, { action: 'login' })Visualization
# Generate HTML timeline visualization
generator = EventSystem::Visualization::TimelineGenerator.new(manager.storage)
html_file = generator.generate_timeline('session_123', 'timeline.html')
# Get event summary
summary = generator.event_summary('session_123')
puts summary
# => {"user_created" => 5, "order_placed" => 3, "payment_received" => 2}
# Get timeline data for custom visualizations
timeline_data = generator.timeline_data('session_123')CLI Tool
The gem includes a command-line tool for managing events:
# Generate timeline visualization
event_system visualize session_123 timeline.html
# Show statistics
event_system stats
# List available sessions
event_system list
# Query events
event_system query session_123 order_placed
# Use file storage
event_system -s file -d /path/to/logs visualizeAdvanced Configuration
# Custom configuration
config = EventSystem::Configuration.new
config.storage_type = :file
config.storage_options = { directory: 'custom_logs' }
config.session_id = 'production_session'
config.auto_flush = true
# Custom logger
require 'logger'
config.logger = Logger.new('event_system.log')
manager = EventSystem.create_manager(config)Error Handling
# Subscribers with error handling
class SafeSubscriber
include EventSystem::EventSubscriber
def handle_event(event)
# Your event handling logic
process_event(event)
rescue => e
# Errors are automatically logged by the event manager
puts "Error processing event: #{e.message}"
end
endAPI Reference
EventSystem Module
-
EventSystem.create_manager(config = nil)- Create a new event manager -
EventSystem.create_event(type, source = nil, data = {})- Create a new event -
EventSystem.version- Get the current version
EventManager Class
-
#publish(event)- Publish an event -
#publish_event(type, source = nil, data = {})- Create and publish an event -
#subscribe(event_type, subscriber)- Subscribe to specific event type -
#subscribe_all(subscriber)- Subscribe to all events -
#unsubscribe(event_type, subscriber)- Unsubscribe from event type -
#query_events(options = {})- Query events with filters -
#switch_session(session_id)- Switch to different session -
#create_session(session_id = nil)- Create new session -
#stats- Get system statistics -
#close- Close the event manager
Event Class
-
#id- Unique event identifier -
#type- Event type -
#source- Event source -
#data- Event data -
#timestamp- Event timestamp -
#to_json- JSON representation -
#to_h- Hash representation -
Event.from_json(json)- Create event from JSON
Storage Backends
-
EventSystem::Storage::MemoryStore- In-memory storage -
EventSystem::Storage::FileStore- File-based storage -
EventSystem::Storage::Base- Abstract base class for custom storage
Examples
Web Application
class WebApp
def initialize
@event_manager = EventSystem.create_manager(
storage_type: :file,
storage_options: { directory: 'logs/events' }
)
# Subscribe to web events
@event_manager.subscribe(:request_received, self)
@event_manager.subscribe(:response_sent, self)
end
def handle_request(request)
@event_manager.publish_event(:request_received, self, {
path: request.path,
method: request.method,
ip: request.ip
})
end
def handle_event(event)
# Log web events
puts "Web event: #{event.type} - #{event.data}"
end
endMicroservice Communication
class OrderService
def initialize
@event_manager = EventSystem.create_manager
@event_manager.subscribe(:payment_processed, self)
end
def place_order(order_data)
@event_manager.publish_event(:order_created, self, order_data)
end
def handle_event(event)
if event.type == 'payment_processed'
fulfill_order(event.data[:order_id])
end
end
endTesting
RSpec.describe OrderService do
let(:event_manager) { EventSystem.create_manager(storage_type: :memory) }
let(:service) { OrderService.new(event_manager) }
it 'publishes order created event' do
expect(event_manager).to receive(:publish_event).with(:order_created, service, anything)
service.place_order({ customer_id: 123 })
end
endDevelopment
After checking out the repo, run bin/setup to install dependencies. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/davidslv/event_system.