From efa6a28b1d8a7eaa1b5d2304445ddb5d51136bdd Mon Sep 17 00:00:00 2001 From: rvazarkar Date: Tue, 6 Feb 2024 13:27:01 -0500 Subject: [PATCH] fix: fix retry logic again --- src/CommonLib/LDAPUtils.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/CommonLib/LDAPUtils.cs b/src/CommonLib/LDAPUtils.cs index a547244c..febcdc8f 100644 --- a/src/CommonLib/LDAPUtils.cs +++ b/src/CommonLib/LDAPUtils.cs @@ -65,6 +65,7 @@ private static readonly ConcurrentDictionary private readonly PortScanner _portScanner; private LDAPConfig _ldapConfig = new(); private readonly ManualResetEvent _connectionResetEvent = new(false); + private readonly object _lockObj = new(); /// @@ -884,12 +885,15 @@ public IEnumerable QueryLDAP(string ldapFilter, SearchScope //Always increment retry count retryCount++; - - //If we are the holders of the reset event, we need to do logic to reset the connection - if (_connectionResetEvent.Reset()) + + //Attempt to acquire a lock + if (Monitor.TryEnter(_lockObj)) { + //If we've acquired the lock, we want to immediately signal our reset event so everyone else waits + _connectionResetEvent.Reset(); try { + //Sleep for our backoff Thread.Sleep(backoffDelay); //Explicitly skip the cache so we don't get the same connection back conn = CreateNewConnection(domainName, globalCatalog, true); @@ -904,12 +908,15 @@ public IEnumerable QueryLDAP(string ldapFilter, SearchScope } finally { + //Reset our event + release the lock _connectionResetEvent.Set(); + Monitor.Exit(_lockObj); } } else { //If someone else is holding the reset event, we want to just wait and then pull the newly created connection out of the cache + //This event will be released after the first entrant thread is done making a new connection _connectionResetEvent.WaitOne(); conn = CreateNewConnection(domainName, globalCatalog); }