Migrating Guide: Architecture Improvements (v2.0.0-pre6)
This guide covers the architecture enhancements and new persistence methods in v2.0.0-pre6.
Architecture Improvements
1. Enhanced Persistence Operations
New save_if_not_exists Method:
user = User.new(email: 'user@example.com')
# Only save if the user doesn't already exist
if user.save_if_not_exists
puts "User created successfully"
else
puts "User already exists"
end
Atomic Persistence with Transactions:
user.transaction do |conn|
conn.set(user.key, user.serialize)
conn.sadd("all_users", user.identifier)
conn.expire(user.key, user.ttl) if user.ttl
end
2. Modular Class Structure
The Horreum class structure was reorganized for better maintainability:
Core Modules:
Familia::Horreum::Core- Essential functionalityFamilia::Horreum::ClassMethods- Class-level methodsFamilia::Horreum::Serialization- Object serializationFamilia::Horreum::Commands- Valkey/Redis command wrappers
Feature System Improvements:
- Dependency management between features
- Cleaner feature activation
- Better error handling for missing dependencies
3. Enhanced Error Handling
New Exception Types:
begin
user.save!
rescue Familia::PersistenceError => e
puts "Failed to save: #{e.}"
rescue Familia::ValidationError => e
puts "Validation failed: #{e.}"
end
Improved Data Consistency:
- Automatic retry for transient Valkey/Redis connection issues
- Better handling of concurrent modifications
- Enhanced validation before persistence operations
Migration Steps
1. Update Error Handling
Before (v2.0.0-pre5):
begin
user.save
rescue => e
puts "Something went wrong: #{e}"
end
After (v2.0.0-pre6):
begin
user.save
rescue Familia::PersistenceError => e
puts "Persistence failed: #{e.}"
# Handle specific persistence issues
rescue Familia::ValidationError => e
puts "Invalid data: #{e.}"
# Handle validation failures
end
2. Adopt Conditional Persistence
Replace existence checks with atomic operations:
Before:
user = User.new(email: email)
unless User.exists?(email)
user.save
end
After:
user = User.new(email: email)
user.save_if_not_exists
3. Leverage Transaction Support
For complex operations, use transactions:
# Before - Multiple separate operations
user.save
user..add(tag)
user.scores.add(score, )
# After - Atomic transaction
user.transaction do |conn|
conn.set(user.key, user.serialize)
conn.sadd(user..key, tag)
conn.zadd(user.scores.key, , score)
end
Performance Improvements
Connection Management
- Improved connection pooling with better resource utilization
- Reduced connection overhead through intelligent connection reuse
- Enhanced concurrent operation support
Feature System
- Lazy feature loading reduces memory footprint
- Optimized method dispatch for feature methods
- Better dependency resolution
Breaking Changes
Method Signatures
- Some internal methods changed signatures for better consistency
- Error handling improved with specific exception types
- Transaction block interface standardized
Feature Dependencies
- Features now explicitly declare dependencies
- Better error messages for missing feature requirements
- Automatic dependency resolution where possible
Next Steps
After completing architecture migration:
- Explore Relationships Migration for the comprehensive relationship system
- Review updated documentation for architectural patterns
- Consider adopting new persistence patterns in your application