Module: Familia::Features::ObjectIdentifier
- Defined in:
- lib/familia/features/object_identifier.rb
Overview
ObjectIdentifier is a feature that provides unique object identifier management with configurable generation strategies. Object identifiers are crucial for distinguishing objects in distributed systems and providing stable references.
Object identifiers are: - Unique across the system - Persistent (stored in Redis/Valkey) - Lazily generated (only when first accessed) - Configurable (multiple generation strategies available) - Preserved during initialization (existing IDs never regenerated)
Generation Strategies: - :uuid_v7 (default) - UUID version 7 with embedded timestamp for sortability - :uuid_v4 - UUID version 4 for compatibility with legacy systems - :hex - High-entropy hexadecimal identifier using SecureIdentifier - Proc - Custom generation logic provided as a callable
Example Usage:
# Default UUID v7 generation class User < Familia::Horreum feature :object_identifier field :email end
user = User.new(email: ‘user@example.com’) user.objid # => “01234567-89ab-7def-8000-123456789abc” (UUID v7)
# UUID v4 for legacy compatibility class LegacyUser < Familia::Horreum feature :object_identifier, generator: :uuid_v4 field :email end
legacy = LegacyUser.new(email: ‘legacy@example.com’) legacy.objid # => “f47ac10b-58cc-4372-a567-0e02b2c3d479” (UUID v4)
# High-entropy hex for security-sensitive applications class SecureDocument < Familia::Horreum feature :object_identifier, generator: :hex field :title end
doc = SecureDocument.new(title: ‘Classified’) doc.objid # => “a1b2c3d4e5f6…” (256-bit hex)
# Custom generation strategy class TimestampedItem < Familia::Horreum feature :object_identifier, generator: -> { “item_#Time.now.to_i_#SecureRandom.hex(4)” } field :data end
item = TimestampedItem.new(data: ‘test’) item.objid # => “item_1693857600_a1b2c3d4”
Data Integrity Guarantees:
The feature preserves the object identifier passed during initialization, ensuring that existing objects loaded from Redis maintain their IDs:
# Loading existing object from Redis preserves ID existing = User.new(objid: ‘existing-uuid-value’, email: ‘existing@example.com’) existing.objid # => “existing-uuid-value” (preserved, not regenerated)
Performance Characteristics:
- Lazy Generation: IDs generated only when first accessed
- Thread-Safe: Generator strategy configured once during initialization
- Memory Efficient: No unnecessary ID generation for unused objects
- Redis Efficient: Only persists non-nil values to conserve memory
Security Considerations:
- UUID v7 includes timestamp information (may leak timing data)
- UUID v4 provides strong randomness without timing correlation
- Hex generator provides maximum entropy (256 bits) for security-critical use cases
- Custom generators allow domain-specific security requirements
Defined Under Namespace
Modules: ClassMethods Classes: ObjectIdentifierFieldType
Constant Summary collapse
- DEFAULT_GENERATOR =
:uuid_v7
Instance Method Summary collapse
-
#init ⇒ Object
Initialize object identifier configuration.
-
#object_identifier ⇒ String
Full-length alias for objid for clarity when needed.
-
#object_identifier=(value) ⇒ Object
Full-length alias setter for objid.
Instance Method Details
#init ⇒ Object
Initialize object identifier configuration
Called during object initialization to set up the ID generation strategy. This hook is called AFTER field initialization, ensuring that any objid values passed during construction are preserved.
290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/familia/features/object_identifier.rb', line 290 def init super if defined?(super) # The generator strategy is configured at the class level via feature options. # We don't need to store it per-instance since it's consistent for the class. # The actual generation happens lazily in the getter when needed. return unless Familia.debug? = self.class.(:object_identifier) generator = [:generator] || DEFAULT_GENERATOR Familia.trace :OBJID_INIT, dbclient, "Generator strategy: #{generator}", caller(1..1) end |
#object_identifier ⇒ String
Full-length alias for objid for clarity when needed
272 273 274 |
# File 'lib/familia/features/object_identifier.rb', line 272 def object_identifier objid end |
#object_identifier=(value) ⇒ Object
Full-length alias setter for objid
280 281 282 |
# File 'lib/familia/features/object_identifier.rb', line 280 def object_identifier=(value) self.objid = value end |