Fix/websocket queue to main thread (#443)
* feat: Implement async method to retrieve enabled tools on the main thread * fix: cancelable main-thread tool discovery * chore: dispose cancellation registration and dedupe usings --------- Co-authored-by: Jordon Harrison <Jordon.Harrison@outlook.com>main
parent
fd44ab3b5d
commit
0c8d2aac42
|
|
@ -8,9 +8,11 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MCPForUnity.Editor.Config;
|
using MCPForUnity.Editor.Config;
|
||||||
using MCPForUnity.Editor.Helpers;
|
using MCPForUnity.Editor.Helpers;
|
||||||
|
using MCPForUnity.Editor.Services;
|
||||||
using MCPForUnity.Editor.Services.Transport;
|
using MCPForUnity.Editor.Services.Transport;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MCPForUnity.Editor.Services.Transport.Transports
|
namespace MCPForUnity.Editor.Services.Transport.Transports
|
||||||
|
|
@ -65,6 +67,39 @@ namespace MCPForUnity.Editor.Services.Transport.Transports
|
||||||
public string TransportName => TransportDisplayName;
|
public string TransportName => TransportDisplayName;
|
||||||
public TransportState State => _state;
|
public TransportState State => _state;
|
||||||
|
|
||||||
|
private Task<List<ToolMetadata>> GetEnabledToolsOnMainThreadAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
var tcs = new TaskCompletionSource<List<ToolMetadata>>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
|
|
||||||
|
// Register cancellation to break the deadlock if StopAsync is called while waiting for main thread
|
||||||
|
var registration = token.Register(() => tcs.TrySetCanceled());
|
||||||
|
|
||||||
|
EditorApplication.delayCall += () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (tcs.Task.IsCompleted)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tools = _toolDiscoveryService?.GetEnabledTools() ?? new List<ToolMetadata>();
|
||||||
|
tcs.TrySetResult(tools);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
tcs.TrySetException(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Ensure registration is disposed even if discovery throws
|
||||||
|
registration.Dispose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return tcs.Task;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<bool> StartAsync()
|
public async Task<bool> StartAsync()
|
||||||
{
|
{
|
||||||
// Capture identity values on the main thread before any async context switching
|
// Capture identity values on the main thread before any async context switching
|
||||||
|
|
@ -421,7 +456,9 @@ namespace MCPForUnity.Editor.Services.Transport.Transports
|
||||||
{
|
{
|
||||||
if (_toolDiscoveryService == null) return;
|
if (_toolDiscoveryService == null) return;
|
||||||
|
|
||||||
var tools = _toolDiscoveryService.GetEnabledTools();
|
token.ThrowIfCancellationRequested();
|
||||||
|
var tools = await GetEnabledToolsOnMainThreadAsync(token).ConfigureAwait(false);
|
||||||
|
token.ThrowIfCancellationRequested();
|
||||||
McpLog.Info($"[WebSocket] Preparing to register {tools.Count} tool(s) with the bridge.");
|
McpLog.Info($"[WebSocket] Preparing to register {tools.Count} tool(s) with the bridge.");
|
||||||
var toolsArray = new JArray();
|
var toolsArray = new JArray();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,6 @@ using UnityEditor.UIElements;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UIElements;
|
using UnityEngine.UIElements;
|
||||||
using MCPForUnity.Editor.Constants;
|
using MCPForUnity.Editor.Constants;
|
||||||
using MCPForUnity.Editor.Helpers;
|
|
||||||
using MCPForUnity.Editor.Services;
|
|
||||||
using MCPForUnity.Editor.Windows.Components.Settings;
|
|
||||||
using MCPForUnity.Editor.Windows.Components.Connection;
|
|
||||||
using MCPForUnity.Editor.Windows.Components.ClientConfig;
|
|
||||||
using MCPForUnity.Editor.Windows.Components.Tools;
|
using MCPForUnity.Editor.Windows.Components.Tools;
|
||||||
|
|
||||||
namespace MCPForUnity.Editor.Windows
|
namespace MCPForUnity.Editor.Windows
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue