Optimize PostgreSQL dead tuple handling for media scans

Introduce bulk operation extensions and transaction helpers for efficient, batched EF Core operations. Refactor MediaStreamInfo schema by splitting audio/video details into dedicated tables, reducing table bloat and improving update performance. Add migration for data movement and schema changes. Update EF Core models and context for new structure. Enhance PostgreSQL provider configuration and add comprehensive documentation and monitoring guides. Includes minor middleware and code cleanups.
This commit is contained in:
2026-04-30 15:52:37 -04:00
parent 6d5282208b
commit 57d6342524
20 changed files with 1995 additions and 339 deletions
@@ -44,7 +44,7 @@ public class WebSocketAuthenticationMiddleware
public async Task Invoke(HttpContext httpContext, IAuthService authService)
{
// Only process WebSocket upgrade requests on the /socket endpoint
if (httpContext.WebSockets.IsWebSocketRequestUpgrade
if (httpContext.WebSockets.IsWebSocketRequest
&& httpContext.Request.Path.StartsWithSegments("/socket", StringComparison.OrdinalIgnoreCase))
{
await AuthenticateWebSocketRequest(httpContext, authService).ConfigureAwait(false);
@@ -66,7 +66,8 @@ public class WebSocketAuthenticationMiddleware
// Extract api_key from query string
if (!httpContext.Request.Query.TryGetValue("api_key", out var apiKeyValues) || apiKeyValues.Count == 0)
{
_logger.LogDebug("WebSocket connection attempted without api_key query parameter. IP: {IP}",
_logger.LogDebug(
"WebSocket connection attempted without api_key query parameter. IP: {IP}",
httpContext.Connection.RemoteIpAddress);
return;
}
@@ -74,7 +75,8 @@ public class WebSocketAuthenticationMiddleware
var apiKey = apiKeyValues[0];
if (string.IsNullOrWhiteSpace(apiKey))
{
_logger.LogDebug("WebSocket connection attempted with empty api_key. IP: {IP}",
_logger.LogDebug(
"WebSocket connection attempted with empty api_key. IP: {IP}",
httpContext.Connection.RemoteIpAddress);
return;
}
@@ -84,7 +86,8 @@ public class WebSocketAuthenticationMiddleware
if (!authorizationInfo.HasToken)
{
_logger.LogDebug("WebSocket authentication failed: Invalid or expired token. IP: {IP}",
_logger.LogDebug(
"WebSocket authentication failed: Invalid or expired token. IP: {IP}",
httpContext.Connection.RemoteIpAddress);
return;
}
@@ -114,23 +117,19 @@ public class WebSocketAuthenticationMiddleware
var principal = new ClaimsPrincipal(identity);
httpContext.User = principal;
_logger.LogDebug("WebSocket authentication successful for user {Username}. IP: {IP}",
_logger.LogDebug(
"WebSocket authentication successful for user {Username}. IP: {IP}",
authorizationInfo.User?.Username ?? "Unknown",
httpContext.Connection.RemoteIpAddress);
}
catch (Exception ex)
{
_logger.LogDebug(ex, "Error during WebSocket authentication. IP: {IP}",
_logger.LogDebug(
ex,
"Error during WebSocket authentication. IP: {IP}",
httpContext.Connection.RemoteIpAddress);
}
}
}
/// <summary>
/// Adds WebSocket authentication to the application pipeline.
/// </summary>
/// <param name="appBuilder">The application builder.</param>
/// <returns>The updated application builder.</returns>
public static IApplicationBuilder UseWebSocketAuthentication(this IApplicationBuilder appBuilder)
{
return appBuilder.UseMiddleware<WebSocketAuthenticationMiddleware>();
}