Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ private enum TransportProtocol
private Button testConnectionButton;

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
public event Action OnManualConfigUpdateRequested;
Expand Down Expand Up @@ -173,7 +181,7 @@ public void UpdateConnectionStatus()
statusIndicator.AddToClassList("disconnected");
connectionToggleButton.text = "Start Session";

healthStatusLabel.text = "Unknown";
healthStatusLabel.text = HealthStatusUnknown;
healthIndicator.RemoveFromClassList("healthy");
healthIndicator.RemoveFromClassList("warning");
healthIndicator.AddToClassList("unknown");
Expand Down Expand Up @@ -408,15 +416,33 @@ private async void OnTestConnectionClicked()
}

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;
if (!bridgeService.IsRunning)
{
healthStatusLabel.text = "Disconnected";
healthStatusLabel.text = HealthStatusUnknown;
healthIndicator.RemoveFromClassList("healthy");
healthIndicator.RemoveFromClassList("warning");
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;
}

Expand All @@ -426,23 +452,45 @@ public async Task VerifyBridgeConnectionAsync()
healthIndicator.RemoveFromClassList("warning");
healthIndicator.RemoveFromClassList("unknown");

string newStatus;
if (result.Success && result.PingSucceeded)
{
healthStatusLabel.text = "Healthy";
newStatus = HealthStatusHealthy;
healthStatusLabel.text = newStatus;
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)
{
healthStatusLabel.text = "Ping Failed";
newStatus = HealthStatusPingFailed;
healthStatusLabel.text = newStatus;
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
{
healthStatusLabel.text = "Unhealthy";
newStatus = HealthStatusUnhealthy;
healthStatusLabel.text = newStatus;
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;
}
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class MCPForUnityEditorWindow : EditorWindow

private static readonly HashSet<MCPForUnityEditorWindow> OpenWindows = new();
private bool guiCreated = false;
private double lastRefreshTime = 0;
private const double RefreshDebounceSeconds = 0.5;

public static void ShowWindow()
{
Expand Down Expand Up @@ -181,6 +183,14 @@ private void OnEditorUpdate()

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();

if (MCPServiceLocator.Bridge.IsRunning)
Expand Down