FileCacheDriver class

A file-based cache driver implementation for the Khadem framework.

This driver stores cache data as JSON files on the local filesystem, providing a persistent caching solution suitable for single-server applications or development environments. Each cache entry is stored as a separate file with metadata including expiration time and TTL information.

Key Features

  • Persistent Storage: Cache data survives application restarts
  • TTL Support: Automatic expiration of cache entries with cleanup
  • File Handle Management: Proper cleanup with Windows compatibility
  • Key Sanitization: Safe file naming for cache keys
  • Compression: Optional gzip compression for large values (>1KB)
  • Statistics: Built-in performance metrics with persistent storage
  • Error Handling: Robust error handling with graceful degradation
  • Cross-Platform: Optimized for both Unix and Windows file systems
  • Async Operations: Non-blocking metadata persistence

Thread Safety

This implementation is not thread-safe for concurrent access to the same cache directory. Dart isolates do not share memory, and file locks are not implemented in this driver. Concurrent access from multiple isolates or processes is not safe. For multi-threaded applications, use different cache directories or implement external synchronization mechanisms.

Usage

// Create a file cache driver with default settings
final cache = FileCacheDriver();

// Create with custom directory
final cache = FileCacheDriver(cacheDir: '/tmp/my_cache');

// Create with custom settings
final cache = FileCacheDriver(
  cacheDir: '/var/cache/myapp',
  maxFileSize: 50 * 1024 * 1024, // 50MB
  compressionThreshold: 2048, // 2KB
  enableCompression: true,
);

// Store data with TTL
await cache.put('user:123', {'name': 'John', 'email': 'john@example.com'}, Duration(hours: 1));

// Retrieve data
final user = await cache.get('user:123');

// Check if key exists
final exists = await cache.has('user:123');

// Remove specific key
await cache.forget('user:123');

// Clear all cache
await cache.clear();

// Get cache statistics
final stats = cache.getStats();
print('Hit rate: ${stats.hitRate}%');

Configuration

The driver accepts the following configuration options:

  • cacheDir: Directory path for cache storage (default: 'storage/cache')
  • maxFileSize: Maximum file size in bytes (default: 10MB)
  • compressionThreshold: Size threshold for compression (default: 1KB)
  • enableCompression: Whether to enable gzip compression (default: true)
  • filePermissions: File permissions for cache files (default: 0644)

Performance Considerations

  • File I/O operations are generally slower than memory-based caches
  • Suitable for caching large objects or data that needs persistence
  • Consider using memory cache for frequently accessed small data
  • Monitor disk space usage as cache files accumulate
  • Windows file handle management includes delays to prevent access conflicts
  • Statistics are persisted asynchronously to avoid blocking operations

Error Handling

The driver handles various error conditions:

  • Invalid cache directory paths
  • File system permission issues
  • Disk space exhaustion
  • Corrupted cache files (automatic cleanup)
  • Concurrent access conflicts
  • Windows file handle locking (with retry mechanisms)
  • Compression/decompression failures
  • Metadata persistence failures (graceful degradation)
Implemented types

Constructors

FileCacheDriver({String cacheDir = 'storage/cache', int maxFileSize = 10 * 1024 * 1024, int compressionThreshold = 1024, bool enableCompression = true, int filePermissions = 0x644})
Creates a new FileCacheDriver instance.

Properties

cacheDirectory String
Gets the cache directory path.
no setter
compressionEnabled bool
Checks if compression is enabled.
no setter
compressionThreshold int
Gets the compression threshold.
no setter
hashCode int
The hash code for this object.
no setterinherited
maxFileSize int
Gets the maximum file size limit.
no setter
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

add(String key, dynamic value, Duration ttl) Future<bool>
Stores a value in the cache if the key does not exist.
override
clear() Future<void>
Clears all items from the cache.
override
decrement(String key, [int amount = 1]) Future<int>
Decrement the value of an item in the cache.
override
forget(String key) Future<void>
Removes a value from the cache by its key.
override
get(String key) Future
Retrieves a value from the cache by its key.
override
getStats() CacheStats
Gets cache statistics.
has(String key) Future<bool>
Checks if a key exists in the cache and has not expired.
override
increment(String key, [int amount = 1]) Future<int>
Increment the value of an item in the cache.
override
many(List<String> keys) Future<Map<String, dynamic>>
Retrieves multiple values from the cache by their keys.
override
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
pull(String key) Future
Retrieve an item from the cache and delete it.
override
put(String key, dynamic value, Duration ttl) Future<void>
Stores a value in the cache with a specified time-to-live (TTL).
override
putMany(Map<String, dynamic> values, Duration ttl) Future<void>
Stores multiple values in the cache.
override
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited