Fix duplicate connection verification logs: add debounce and state-ch… (#413)
* Fix duplicate connection verification logs: add debounce and state-change-only logging * Address CodeRabbit feedback: use status constants, fix comments, remove redundant codemain
parent
b57a2ece9d
commit
50f612cbf2
|
|
@ -44,6 +44,14 @@ namespace MCPForUnity.Editor.Windows.Components.Connection
|
||||||
private Button testConnectionButton;
|
private Button testConnectionButton;
|
||||||
|
|
||||||
private bool connectionToggleInProgress;
|
private bool connectionToggleInProgress;
|
||||||
|
private Task verificationTask;
|
||||||
|
private string lastHealthStatus;
|
||||||
|
|
||||||
|
// Health status constants
|
||||||
|
private const string HealthStatusUnknown = "Unknown";
|
||||||
|
private const string HealthStatusHealthy = "Healthy";
|
||||||
|
private const string HealthStatusPingFailed = "Ping Failed";
|
||||||
|
private const string HealthStatusUnhealthy = "Unhealthy";
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
public event Action OnManualConfigUpdateRequested;
|
public event Action OnManualConfigUpdateRequested;
|
||||||
|
|
@ -173,7 +181,7 @@ namespace MCPForUnity.Editor.Windows.Components.Connection
|
||||||
statusIndicator.AddToClassList("disconnected");
|
statusIndicator.AddToClassList("disconnected");
|
||||||
connectionToggleButton.text = "Start Session";
|
connectionToggleButton.text = "Start Session";
|
||||||
|
|
||||||
healthStatusLabel.text = "Unknown";
|
healthStatusLabel.text = HealthStatusUnknown;
|
||||||
healthIndicator.RemoveFromClassList("healthy");
|
healthIndicator.RemoveFromClassList("healthy");
|
||||||
healthIndicator.RemoveFromClassList("warning");
|
healthIndicator.RemoveFromClassList("warning");
|
||||||
healthIndicator.AddToClassList("unknown");
|
healthIndicator.AddToClassList("unknown");
|
||||||
|
|
@ -408,15 +416,33 @@ namespace MCPForUnity.Editor.Windows.Components.Connection
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task VerifyBridgeConnectionAsync()
|
public async Task VerifyBridgeConnectionAsync()
|
||||||
|
{
|
||||||
|
// Prevent concurrent verification calls
|
||||||
|
if (verificationTask != null && !verificationTask.IsCompleted)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
verificationTask = VerifyBridgeConnectionInternalAsync();
|
||||||
|
await verificationTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task VerifyBridgeConnectionInternalAsync()
|
||||||
{
|
{
|
||||||
var bridgeService = MCPServiceLocator.Bridge;
|
var bridgeService = MCPServiceLocator.Bridge;
|
||||||
if (!bridgeService.IsRunning)
|
if (!bridgeService.IsRunning)
|
||||||
{
|
{
|
||||||
healthStatusLabel.text = "Disconnected";
|
healthStatusLabel.text = HealthStatusUnknown;
|
||||||
healthIndicator.RemoveFromClassList("healthy");
|
healthIndicator.RemoveFromClassList("healthy");
|
||||||
healthIndicator.RemoveFromClassList("warning");
|
healthIndicator.RemoveFromClassList("warning");
|
||||||
healthIndicator.AddToClassList("unknown");
|
healthIndicator.AddToClassList("unknown");
|
||||||
McpLog.Warn("Cannot verify connection: Bridge is not running");
|
|
||||||
|
// Only log if state changed
|
||||||
|
if (lastHealthStatus != HealthStatusUnknown)
|
||||||
|
{
|
||||||
|
McpLog.Warn("Cannot verify connection: Bridge is not running");
|
||||||
|
lastHealthStatus = HealthStatusUnknown;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -426,23 +452,45 @@ namespace MCPForUnity.Editor.Windows.Components.Connection
|
||||||
healthIndicator.RemoveFromClassList("warning");
|
healthIndicator.RemoveFromClassList("warning");
|
||||||
healthIndicator.RemoveFromClassList("unknown");
|
healthIndicator.RemoveFromClassList("unknown");
|
||||||
|
|
||||||
|
string newStatus;
|
||||||
if (result.Success && result.PingSucceeded)
|
if (result.Success && result.PingSucceeded)
|
||||||
{
|
{
|
||||||
healthStatusLabel.text = "Healthy";
|
newStatus = HealthStatusHealthy;
|
||||||
|
healthStatusLabel.text = newStatus;
|
||||||
healthIndicator.AddToClassList("healthy");
|
healthIndicator.AddToClassList("healthy");
|
||||||
McpLog.Debug($"Connection verification successful: {result.Message}");
|
|
||||||
|
// Only log if state changed
|
||||||
|
if (lastHealthStatus != newStatus)
|
||||||
|
{
|
||||||
|
McpLog.Debug($"Connection verification successful: {result.Message}");
|
||||||
|
lastHealthStatus = newStatus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (result.HandshakeValid)
|
else if (result.HandshakeValid)
|
||||||
{
|
{
|
||||||
healthStatusLabel.text = "Ping Failed";
|
newStatus = HealthStatusPingFailed;
|
||||||
|
healthStatusLabel.text = newStatus;
|
||||||
healthIndicator.AddToClassList("warning");
|
healthIndicator.AddToClassList("warning");
|
||||||
McpLog.Warn($"Connection verification warning: {result.Message}");
|
|
||||||
|
// Log once per distinct warning state
|
||||||
|
if (lastHealthStatus != newStatus)
|
||||||
|
{
|
||||||
|
McpLog.Warn($"Connection verification warning: {result.Message}");
|
||||||
|
lastHealthStatus = newStatus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
healthStatusLabel.text = "Unhealthy";
|
newStatus = HealthStatusUnhealthy;
|
||||||
|
healthStatusLabel.text = newStatus;
|
||||||
healthIndicator.AddToClassList("warning");
|
healthIndicator.AddToClassList("warning");
|
||||||
McpLog.Error($"Connection verification failed: {result.Message}");
|
|
||||||
|
// Log once per distinct error state
|
||||||
|
if (lastHealthStatus != newStatus)
|
||||||
|
{
|
||||||
|
McpLog.Error($"Connection verification failed: {result.Message}");
|
||||||
|
lastHealthStatus = newStatus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ namespace MCPForUnity.Editor.Windows
|
||||||
|
|
||||||
private static readonly HashSet<MCPForUnityEditorWindow> OpenWindows = new();
|
private static readonly HashSet<MCPForUnityEditorWindow> OpenWindows = new();
|
||||||
private bool guiCreated = false;
|
private bool guiCreated = false;
|
||||||
|
private double lastRefreshTime = 0;
|
||||||
|
private const double RefreshDebounceSeconds = 0.5;
|
||||||
|
|
||||||
public static void ShowWindow()
|
public static void ShowWindow()
|
||||||
{
|
{
|
||||||
|
|
@ -181,6 +183,14 @@ namespace MCPForUnity.Editor.Windows
|
||||||
|
|
||||||
private void RefreshAllData()
|
private void RefreshAllData()
|
||||||
{
|
{
|
||||||
|
// Debounce rapid successive calls (e.g., from OnFocus being called multiple times)
|
||||||
|
double currentTime = EditorApplication.timeSinceStartup;
|
||||||
|
if (currentTime - lastRefreshTime < RefreshDebounceSeconds)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastRefreshTime = currentTime;
|
||||||
|
|
||||||
connectionSection?.UpdateConnectionStatus();
|
connectionSection?.UpdateConnectionStatus();
|
||||||
|
|
||||||
if (MCPServiceLocator.Bridge.IsRunning)
|
if (MCPServiceLocator.Bridge.IsRunning)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue