Circular Dependency Analyse & Oplossingsvoorstel
π DEEP DIVE: De Circular Dependency Chainβ
Huidige Situatieβ
Het Probleemβ
1. Softwarecatalog importeert en ziet dependency op opencatalogi
{
"dependencies": [{
"type": "nextcloud-app",
"app": "opencatalogi",
"required": true
}]
}
2. ImportHandler roept handleNextcloudAppDependencies() aan
- Checkt of opencatalogi enabled is
- Zo niet:
$appManager->enableApp('opencatalogi')
3. Nextcloud boot proces voor opencatalogi start
// opencatalogi/lib/AppInfo/Application.php:75
$settingsService->initialize();
4. SettingsService->initialize() roept loadSettings()
// opencatalogi/lib/Service/SettingsService.php:249
if ($this->shouldLoadSettings()) {
$this->loadSettings();
}
5. loadSettings() roept ConfigurationService->importFromApp()
// SettingsService.php:634
return $configurationService->importFromApp(
appId: 'opencatalogi',
data: $data,
version: $currentAppVersion,
force: $force
);
6. Dit triggert WEER ImportHandler->importFromJson()
- Die WEER
handleNextcloudAppDependencies()zou kunnen aanroepen - INFINITE LOOP als opencatalogi ook dependencies heeft
π― OPLOSSINGSVOORSTELLENβ
Optie 1: Guard Flag (Simpelst, Meest Robuust)β
Voeg een import context flag toe die voorkomt dat dependency checking recursief wordt aangeroepen.
Implementatie:β
// ImportHandler.php
private static bool $isDependencyCheckActive = false;
private function handleNextcloudAppDependencies(array $configData): void
{
// Prevent recursive dependency checking
if (self::$isDependencyCheckActive === true) {
$this->logger->debug('Skipping dependency check - already in dependency resolution context');
return;
}
$dependencies = $configData['x-openregister']['dependencies'] ?? [];
if (empty($dependencies) === true) {
return;
}
// Set guard flag
self::$isDependencyCheckActive = true;
try {
// ... existing dependency handling code ...
foreach ($dependencies as $dependency) {
// ... enable apps ...
}
} finally {
// Always reset flag, even on exception
self::$isDependencyCheckActive = false;
}
}
Voordelen:
- β Simpel te implementeren
- β Voorkomt alle recursie
- β Geen breaking changes
- β Works met elke dependency chain
Nadelen:
- β οΈ Global state (static property)