From b636f454cfbeb1ca4f0fbb3039196e0c90214472 Mon Sep 17 00:00:00 2001 From: Meik Date: Wed, 18 Mar 2026 15:32:03 +0100 Subject: [PATCH] Replace traverse sleep with bounded retry --- LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs | 72 +++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs b/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs index c0ebb3a..d4ed161 100644 --- a/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs +++ b/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs @@ -3,6 +3,7 @@ using C4IT_IAM_Engine; using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.DirectoryServices; using System.DirectoryServices.AccountManagement; using System.IO; @@ -712,8 +713,7 @@ namespace C4IT_IAM_SET DefaultLogger.LogEntry(LogLevels.Debug, "Verarbeite SecurityGroups bei oberster Ebene."); if (!WhatIf) { - DefaultLogger.LogEntry(LogLevels.Debug, "Warte 3min."); - System.Threading.Thread.Sleep(180000); // 60 Sekunden warten + WaitForNewGlobalGroupsToBecomeResolvable(domainContext); } foreach (var currentSecGroup in newSecurityGroups.IAM_SecurityGroups) { @@ -832,6 +832,74 @@ namespace C4IT_IAM_SET } } + private void WaitForNewGlobalGroupsToBecomeResolvable(PrincipalContext domainContext) + { + if (WhatIf || domainContext == null || newSecurityGroups?.IAM_SecurityGroups == null) + return; + + var pendingGroups = newSecurityGroups.IAM_SecurityGroups + .Where(group => group != null + && group.Scope == GroupScope.Global + && group.CreatedNewEntry + && !string.IsNullOrWhiteSpace(group.UID)) + .ToList(); + if (pendingGroups.Count == 0) + return; + + var pendingNames = pendingGroups + .Select(group => group.Name) + .Where(name => !string.IsNullOrWhiteSpace(name)) + .ToList(); + var retryDelaysMs = new[] { 0, 250, 500, 1000, 2000, 5000 }; + var delayIndex = 0; + var maxWait = TimeSpan.FromMinutes(3); + var waitStopwatch = Stopwatch.StartNew(); + + DefaultLogger.LogEntry(LogLevels.Debug, $"Warte auf neue globale Gruppen fuer Traverse-Verschachtelung: {string.Join(", ", pendingNames)}"); + + while (pendingGroups.Count > 0 && waitStopwatch.Elapsed < maxWait) + { + var delayMs = retryDelaysMs[Math.Min(delayIndex, retryDelaysMs.Length - 1)]; + if (delayMs > 0) + System.Threading.Thread.Sleep(delayMs); + if (delayIndex < retryDelaysMs.Length - 1) + delayIndex++; + + for (var index = pendingGroups.Count - 1; index >= 0; index--) + { + var pendingGroup = pendingGroups[index]; + try + { + using (var groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, IdentityType.Sid, pendingGroup.UID)) + { + if (groupPrincipal == null) + continue; + + DefaultLogger.LogEntry(LogLevels.Debug, $"Neue globale Gruppe fuer Traverse-Verarbeitung aufloesbar: {pendingGroup.Name}"); + pendingGroups.RemoveAt(index); + } + } + catch (Exception ex) + { + DefaultLogger.LogEntry(LogLevels.Debug, $"Neue globale Gruppe '{pendingGroup.Name}' noch nicht aufloesbar: {ex.Message}"); + } + } + } + + if (pendingGroups.Count > 0) + { + var unresolvedNames = pendingGroups + .Select(group => group.Name) + .Where(name => !string.IsNullOrWhiteSpace(name)) + .ToList(); + DefaultLogger.LogEntry(LogLevels.Warning, $"Nicht alle neuen globalen Gruppen waren nach {waitStopwatch.Elapsed.TotalSeconds:F1}s fuer Traverse-Verarbeitung aufloesbar: {string.Join(", ", unresolvedNames)}"); + } + else + { + DefaultLogger.LogEntry(LogLevels.Debug, $"Neue globale Gruppen nach {waitStopwatch.Elapsed.TotalSeconds:F1}s fuer Traverse-Verarbeitung aufloesbar."); + } + } + private ResultToken checkFolder()