Module configuration merging in Zend Framework: ensuring consistent values during zero‑downtime deploys
0 reputation · 24 Jun 2024, 06:12 UTC
0 reputation · 24 Jun 2024, 06:12 UTC
Zend Framework 2/3 merges each module’s configuration array into the application configuration with a deep recursive replace. Nested keys are preserved, but numeric keys are discarded. When multiple modules define the same configuration key, the value from the last loaded module overwrites earlier ones. The load order is taken from the module list in application.config.php, which is not deterministic unless explicitly ordered.
During a rolling deployment, the application may load modules from different code branches concurrently. If the module order or configuration keys differ between branches, the resulting configuration may change unpredictably, potentially breaking services that rely on stable adapters or cache pools. The framework offers no built‑in warning or enforcement of a specific merge strategy.
32775 reputation · 24 Jun 2024, 11:43 UTC
Zend Framework (now Laminas) merges module configurations using a deep recursive replace strategy. While string keys are overwritten by later-loaded modules, numeric keys are silently discarded. This behavior, combined with non-deterministic module loading order, creates instability during rolling deployments where different code branches may be active simultaneously.
The framework determines configuration precedence based solely on the order of modules listed in application.config.php. Without explicit ordering, any change in this list—such as during a deployment with mixed module versions—will produce different merged configurations. This can silently alter critical settings like database adapters, cache pools, or service configurations, leading to inconsistent behavior across application instances.
To ensure consistent configuration across all deployment nodes, implement the following:
modules array in application.config.php is strictly ordered and remains identical across all deployment artifacts. If modules are loaded dynamically, implement deterministic sorting based on version metadata.config/autoload/*.php files, which are merged after all module configurations. This provides a final "source of truth" independent of module load order.The framework provides no built-in mechanism to report duplicate keys. However, you can implement a pre-deployment validation script:
// Conceptual duplicate detection logic
$moduleManager = new ModuleManager($application);
$modules = $moduleManager->getModules();
$seenKeys = [];
foreach ($modules as $name => $module) {
$config = $module->getConfig();
foreach (array_keys($config) as $key) {
if (isset($seenKeys[$key])) {
throw new RuntimeException(
"Duplicate config key '$key' found in $name and {$seenKeys[$key]}"
);
}
$seenKeys[$key] = $name;
}
}
This analysis assumes standard ModuleManager behavior. If your project uses custom ConfigListener implementations, the merge precedence rules may differ. Additionally, numeric keys in module configurations are silently discarded during merging, which can cause unexpected data loss if your configuration relies on indexed arrays.
Before deployment, verify the merged configuration by logging or printing the final configuration array. Confirm that expected keys contain the intended values and that the module order matches your deployment requirements.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.