From c7890aaadb13fb63274dbc630172e92bfbee2cd6 Mon Sep 17 00:00:00 2001 From: "Namhyeon, Go" Date: Tue, 28 Oct 2025 14:12:25 +0900 Subject: [PATCH] Serialize connection creation per key --- .../ConnectionManagerBase.cs | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/WelsonJS.Toolkit/WelsonJS.Launcher/ConnectionManagerBase.cs b/WelsonJS.Toolkit/WelsonJS.Launcher/ConnectionManagerBase.cs index 9bf436f..d2129f5 100644 --- a/WelsonJS.Toolkit/WelsonJS.Launcher/ConnectionManagerBase.cs +++ b/WelsonJS.Toolkit/WelsonJS.Launcher/ConnectionManagerBase.cs @@ -22,6 +22,8 @@ namespace WelsonJS.Launcher { private readonly ConcurrentDictionary _pool = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _openLocks + = new ConcurrentDictionary(); /// /// Creates a unique cache key for the given connection parameters. @@ -61,11 +63,28 @@ namespace WelsonJS.Launcher return existing.Connection; } - RemoveInternal(key, existing.Connection); + var gate = _openLocks.GetOrAdd(key, _ => new SemaphoreSlim(1, 1)); + await gate.WaitAsync(token).ConfigureAwait(false); + try + { + if (_pool.TryGetValue(key, out existing) && IsConnectionHealthy(existing.Connection)) + { + return existing.Connection; + } - var connection = await OpenConnectionAsync(parameters, token).ConfigureAwait(false); - _pool[key] = (connection, parameters); - return connection; + if (existing.Connection != null && !IsConnectionHealthy(existing.Connection)) + { + RemoveInternal(key, existing.Connection); + } + + var connection = await OpenConnectionAsync(parameters, token).ConfigureAwait(false); + _pool[key] = (connection, parameters); + return connection; + } + finally + { + gate.Release(); + } } ///