mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-04 15:24:28 +00:00
Hardened background work against disconnected circuits (#937)
This commit is contained in:
1 parent
99089f853e
commit
f03c2d1c88
44 files changed
+500
-126
No files matched your search
@@ -12,6 +12,7 @@ using AIStudio.Tools.Rust;
|
||||
using AIStudio.Tools.Security;
|
||||
using AIStudio.Tools.Services;
|
||||
|
||||
using Microsoft.AspNetCore.Components.Server.Circuits;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Logging.Console;
|
||||
@@ -195,6 +196,13 @@ internal sealed class Program
|
||||
builder.Services.AddHostedService<RustAvailabilityMonitorService>();
|
||||
builder.Services.AddScoped<NativeShareService>();
|
||||
builder.Services.AddScoped<PluginShareService>();
|
||||
|
||||
//
|
||||
// One circuit state per circuit, and the handler which keeps it up to date. Both are scoped,
|
||||
// because the circuit is the scope: every browser window gets its own pair.
|
||||
//
|
||||
builder.Services.AddScoped<CircuitStateService>();
|
||||
builder.Services.AddScoped<CircuitHandler, AIStudioCircuitHandler>();
|
||||
|
||||
// ReSharper disable AccessToDisposedClosure
|
||||
builder.Services.AddHostedService<RustService>(_ => rust);
|
||||
@@ -243,7 +251,22 @@ internal sealed class Program
|
||||
// Get a program logger:
|
||||
var programLogger = app.Services.GetRequiredService<ILogger<Program>>();
|
||||
programLogger.LogInformation("Starting the AI Studio server.");
|
||||
|
||||
|
||||
//
|
||||
// Observe tasks whose exceptions nobody awaited. We register this before the server starts:
|
||||
// otherwise, everything the startup does — the plugin system, the first message bus traffic —
|
||||
// would fault outside of this handler. The sender of such a task says nothing about where it
|
||||
// came from, which is why we log each inner exception with its own stack trace.
|
||||
//
|
||||
TaskScheduler.UnobservedTaskException += (sender, taskArgs) =>
|
||||
{
|
||||
programLogger.LogError(taskArgs.Exception, $"Unobserved task exception by sender '{sender ?? "n/a"}'.");
|
||||
foreach (var innerException in taskArgs.Exception.Flatten().InnerExceptions)
|
||||
programLogger.LogError(innerException, $"Unobserved task exception detail: {innerException.GetType().FullName}.");
|
||||
|
||||
taskArgs.SetObserved();
|
||||
};
|
||||
|
||||
// Store the service provider (DI). We need it later for some classes,
|
||||
// which are not part of the request pipeline:
|
||||
SERVICE_PROVIDER = app.Services;
|
||||
@@ -295,13 +318,7 @@ internal sealed class Program
|
||||
await encryptionInitializer;
|
||||
await rust.AppIsReady();
|
||||
programLogger.LogInformation("The AI Studio server is ready.");
|
||||
|
||||
TaskScheduler.UnobservedTaskException += (sender, taskArgs) =>
|
||||
{
|
||||
programLogger.LogError(taskArgs.Exception, $"Unobserved task exception by sender '{sender ?? "n/a"}'.");
|
||||
taskArgs.SetObserved();
|
||||
};
|
||||
|
||||
|
||||
await serverTask;
|
||||
|
||||
RUST_SERVICE.Dispose();
|
||||
|
||||
Reference in new issue
Block a user