Add WebAPI middleware for multi-instance Roslyn Bridge routing

Add RoslynBridge.WebApi - ASP.NET Core 8.0 middleware that:
- Provides a centralized REST API for accessing multiple VS instances
- Manages instance registry with discovery by port, solution, or PID
- Proxies requests to the appropriate VS instance
- Tracks request/response history for debugging
- Auto-cleanup of stale instances via background service

Features:
- Health endpoints: /api/health, /api/health/ping
- Roslyn endpoints: /api/roslyn/projects, /api/roslyn/diagnostics, etc.
- Instance management: /api/instances (register, heartbeat, unregister)
- History tracking: /api/history, /api/history/stats
- Swagger UI at root (/) for API documentation
- CORS enabled for web applications

Services:
- InstanceRegistryService: Thread-safe registry of VS instances
- HistoryService: In-memory request/response history (max 1000 entries)
- InstanceCleanupService: Background service to remove stale instances
- RoslynBridgeClient: HTTP client for proxying to VS instances

Update RoslynBridge.sln to include RoslynBridge.WebApi project.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-26 23:51:33 -04:00
parent 716827a665
commit 1cbfba3893
76 changed files with 4322 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
namespace RoslynBridge.WebApi.Services;
/// <summary>
/// Background service that periodically removes stale VS instances
/// </summary>
public class InstanceCleanupService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<InstanceCleanupService> _logger;
private readonly TimeSpan _cleanupInterval = TimeSpan.FromMinutes(1);
private readonly TimeSpan _staleTimeout = TimeSpan.FromMinutes(5);
public InstanceCleanupService(
IServiceProvider serviceProvider,
ILogger<InstanceCleanupService> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Instance cleanup service started");
while (!stoppingToken.IsCancellationRequested)
{
try
{
await Task.Delay(_cleanupInterval, stoppingToken);
// Get the registry service from scope
using var scope = _serviceProvider.CreateScope();
var registryService = scope.ServiceProvider.GetRequiredService<IInstanceRegistryService>();
registryService.RemoveStaleInstances(_staleTimeout);
}
catch (OperationCanceledException)
{
// Expected when stopping
break;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error during instance cleanup");
}
}
_logger.LogInformation("Instance cleanup service stopped");
}
}