VersionManager
Version: 2.0.0
Namespace: gCore\Modules\Managers\Base\VersionManager
Implements: ModuleInterface
Overview
VersionManager provides version tracking and cache invalidation functionality. It manages group-based version numbers that enable automatic cache busting when content changes.
Key Features
- Group-based Versioning - Track versions per cache group
- Automatic Invalidation - Increment versions to bust caches
- Versioned Key Generation - Generate cache keys with version prefixes
- Multi-tenant Isolation - Version namespacing via site_id/node_id
- WordPress Integration - Auto-increment on theme/plugin changes
- Dual Storage - WordPress options API or file-based storage
Architecture
VersionManager maintains version numbers for cache groups:
- Version Registry: In-memory version numbers per group
- Persistent Storage: WordPress options or JSON file
- Key Generation: Versioned cache keys for automatic invalidation
- Event Hooks: Auto-increment on content changes
Capability Vector
[
'versioning' => 1.0,
'cache_busting' => 0.95,
'invalidation' => 0.9,
'tracking' => 0.85
]
Default Cache Groups
| Group | Initial Version | Purpose |
|---|---|---|
core |
1 | Core framework cache |
face |
1 | Frontend/theme cache |
api |
1 | API response cache |
manifest |
1 | Asset manifest cache |
Installation & Initialization
Via gCore (Recommended)
$core = gCore::getInstance();
$versionManager = $core->getService('VersionManager');
Direct Initialization
$versionManager = VersionManager::getInstance();
$versionManager->initialize([
'version_prefix' => 'gCore_',
'auto_increment' => true,
'site_id' => 'mysite',
'node_id' => 'node1',
'storage_path' => '/var/data/versions'
]);
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
version_prefix |
string | 'gCore_' | Prefix for version keys |
auto_increment |
bool | true | Auto-increment on WordPress events |
store_history |
bool | false | Store version history |
debug |
bool | WP_DEBUG | Enable debug logging |
ttl |
int | DAY_IN_SECONDS | Version cache TTL |
storage_path |
string | null | File storage path (non-WP) |
site_id |
string | 'default' | Multi-tenant site identifier |
node_id |
string | 'node1' | Multi-tenant node identifier |
Public API
Version Operations
getVersion(string $group = 'core'): int
Get current version for a group.
$version = $versionManager->getVersion('core'); // e.g., 5
$version = $versionManager->getVersion('api'); // e.g., 3
$version = $versionManager->getVersion('unknown'); // 1 (default)
incrementVersion(string $group = 'core', int $amount = 1): int
Increment version for a group, triggering cache invalidation. Uses gNode GNODE_CACHE_INCR when available for atomic operations.
$newVersion = $versionManager->incrementVersion('core');
// Returns new version number
// Triggers: do_action('gCore_cache_version_incremented', $group, $version)
// Increment by specific amount
$newVersion = $versionManager->incrementVersion('api', 5);
decrementVersion(string $group = 'core', int $amount = 1): int
Decrement version for a group. Uses gNode GNODE_CACHE_DECR when available. Minimum version is 1.
$newVersion = $versionManager->decrementVersion('core');
// Returns new version number (minimum 1)
// Triggers: do_action('gCore_cache_version_decremented', $group, $version)
resetVersion(string $group = 'core', int $resetTo = 1): int
Reset version to a specific value.
$versionManager->resetVersion('core', 1);
// Triggers: do_action('gCore_cache_version_reset', $group, $version)
incrementAllVersions(): void
Increment all registered groups (full cache bust).
$versionManager->incrementAllVersions();
// All groups incremented
// Triggers: do_action('gCore_cache_all_versions_incremented', $versions)
registerGroup(string $group, int $initial_version = 1): bool
Register a new cache group.
$success = $versionManager->registerGroup('custom', 1);
// Returns false if group already exists
// Triggers: do_action('gCore_cache_group_registered', $group, $version)
Version History
getHistory(?string $group = null, int $limit = 50): array
Get version change history.
// Get all history
$history = $versionManager->getHistory(null, 100);
// Get history for specific group
$apiHistory = $versionManager->getHistory('api', 20);
// Returns: [['group' => 'api', 'version' => 5, 'action' => 'increment', 'timestamp' => ...], ...]
clearHistory(?string $group = null): bool
Clear version history.
// Clear all history
$versionManager->clearHistory();
// Clear history for specific group
$versionManager->clearHistory('api');
Key Generation
getPrefix(string $group = 'core'): string
Get versioned prefix for cache keys.
$prefix = $versionManager->getPrefix('core');
// Returns: "v5_core_mysite_node1_"
generateKey(string $key, string $group = 'core'): string
Generate full versioned cache key.
$cacheKey = $versionManager->generateKey('user_data', 'api');
// Returns: "v3_api_mysite_node1_user_data"
WordPress Event Handlers
handleCustomizerSave(): void
Called on customize_save_after hook.
// Automatically increments 'manifest' and 'face' groups
handlePluginUpdate($upgrader, $options): void
Called on upgrader_process_complete hook.
// Increments all versions on theme updates
Module Interface Methods
getInstance(): ModuleInterface
Get singleton instance.
initialize(array $config = []): void
Initialize with configuration.
isInitialized(): bool
Check initialization status.
getConfig(): array
Get current configuration.
updateConfig(array $config): void
Update configuration at runtime.
getStatus(): array
Get status information.
$status = $versionManager->getStatus();
// Returns: initialized, versions, config, groups, site_id, node_id, storage_mode, framework
Usage Examples
Basic Cache Busting
$vm = VersionManager::getInstance();
$vm->initialize(['site_id' => 'shop']);
// Generate versioned cache key
$cacheKey = $vm->generateKey('product_list', 'api');
// "v1_api_shop_node1_product_list"
// Store data with versioned key
$cache->set($cacheKey, $products, 3600);
// When products change, increment version
$vm->incrementVersion('api');
// New key: "v2_api_shop_node1_product_list"
// Old cached data automatically orphaned
Custom Cache Groups
$vm = VersionManager::getInstance();
// Register custom groups
$vm->registerGroup('products', 1);
$vm->registerGroup('categories', 1);
$vm->registerGroup('users', 1);
// Invalidate specific group
$vm->incrementVersion('products');
// Or invalidate everything
$vm->incrementAllVersions();
Integration with CacheManager
// In CacheManager or application code
$vm = $core->getService('VersionManager');
$cm = $core->getService('CacheManager');
// Get versioned key
$key = $vm->generateKey('expensive_query', 'api');
// Cache with version-aware key
$data = $cm->get($key);
if ($data === null) {
$data = expensiveOperation();
$cm->set($key, $data, 3600);
}
// When data changes
$vm->incrementVersion('api');
// Next request gets fresh data
Multi-Tenant Version Isolation
// Site A versions
$vmA = VersionManager::getInstance();
$vmA->initialize(['site_id' => 'site_a', 'node_id' => 'prod1']);
$vmA->getPrefix('core'); // "v1_core_site_a_prod1_"
// Site B has independent versions
// "v3_core_site_b_prod1_"
File-Based Storage (Non-WordPress)
$vm = VersionManager::getInstance();
$vm->initialize([
'storage_path' => '/var/app/data',
'site_id' => 'api_server',
'node_id' => 'worker1'
]);
// Versions stored in: /var/app/data/versions_api_server_worker1.json
Integration Points
Dependencies
| Manager | Relationship | Purpose |
|---|---|---|
| CacheManager | Primary Storage | Version persistence (preferred) |
| gCore | Parent | Service discovery |
| WordPress | Fallback Storage | Options API when CacheManager unavailable |
| File System | Fallback Storage | JSON file when neither available |
WordPress Hooks
VersionManager registers the following hooks:
| Hook | Callback | Purpose |
|---|---|---|
switch_theme |
incrementAllVersions |
Bust all caches on theme switch |
activated_plugin |
incrementAllVersions |
Bust caches on plugin activation |
deactivated_plugin |
incrementAllVersions |
Bust caches on plugin deactivation |
customize_save_after |
handleCustomizerSave |
Bust manifest/face on customizer save |
upgrader_process_complete |
handlePluginUpdate |
Bust caches on theme updates |
WordPress Actions Triggered
// When a single group version increments
do_action('gCore_cache_version_incremented', $group, $newVersion);
// When all versions increment
do_action('gCore_cache_all_versions_incremented', $allVersions);
// When a new group is registered
do_action('gCore_cache_group_registered', $group, $initialVersion);
gNode Integration
VersionManager registers with gNode for capability-based service discovery:
$this->gNodeClient->registerService(
'VersionManager',
$this->capabilityVector,
[
'type' => 'manager',
'tier' => 'TOOL',
'priority' => '250'
]
);
Key Namespacing
Version prefix format:
v{version}_{group}_{site_id}_{node_id}_
Examples:
v1_core_default_node1_- Default namespace, version 1v5_api_shop_prod1_- Shop site, API group, version 5v2_face_blog_node2_- Blog site, face group, version 2
Storage Modes
WordPress Mode
Uses WordPress options API:
// Option name: gCore_cache_versions
get_option('gCore_cache_versions', []);
update_option('gCore_cache_versions', $versions, 'no');
File Mode
Uses JSON file storage:
// File: {storage_path}/versions_{site_id}_{node_id}.json
$json = file_get_contents($storageFile);
$versions = json_decode($json, true);
Error Handling
try {
$versionManager->initialize($config);
} catch (\Exception $e) {
error_log('VersionManager init failed: ' . $e->getMessage());
}
Best Practices
- Use meaningful group names: Match groups to logical cache domains
- Increment selectively: Only increment groups affected by changes
- Register groups early: Set up custom groups during initialization
- Integrate with CacheManager: Always use versioned keys for cached data
- Configure storage_path: For non-WordPress deployments
Troubleshooting
Versions Not Persisting
- In WordPress: Check if
update_optionis working - File mode: Verify
storage_pathis writable - Check file permissions on JSON storage
Cache Not Invalidating
- Verify version was incremented (
getVersion()) - Confirm cache key uses
generateKey()orgetPrefix() - Check correct group is being incremented
Multi-Tenant Issues
- Ensure unique
site_idper tenant - Verify
node_idmatches across nodes - Check key prefix generation