fix(centralui): P6-12 — dispose sandbox-run CTS in ApiMethodForm + SharedScriptForm
Neither Test Run form implemented IDisposable, so navigating away mid-run left _runCts uncancelled: the sandbox kept the run alive until its own internal script timeout, and the eventual continuation touched a torn-down component's _running/_runResult fields. TemplateScriptDialog already got this right — both forms now mirror it exactly: @implements IDisposable plus a Dispose() that cancels + disposes _runCts. ScriptAnalysisService.RunInSandboxAsync is marked virtual (test-only seam, mirroring the existing virtual on DebugStreamService.StartStreamAsync/ StopStream) so a TaskCompletionSource-gated stub can hold a run open deterministically. New bUnit tests (ScriptFormSandboxDisposalTests) prove, for both forms: disposing mid-run cancels the token the sandbox observed, and the cancelled continuation resolves with no unhandled exception and no _runResult/ _running mutation. Proof of failure: reverting only the two .razor changes (keeping the virtual seam) reproduces all 4 failures — the token is never cancelled and the no-op assertions time out.
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
@inject IInboundApiKeyAdmin ApiKeyAdmin
|
||||
@inject ScriptAnalysis.ScriptAnalysisService AnalysisService
|
||||
@inject NavigationManager NavigationManager
|
||||
@implements IDisposable
|
||||
|
||||
<div class="container-fluid mt-3">
|
||||
<button class="btn btn-outline-secondary btn-sm mb-2" @onclick="GoBack">← Back</button>
|
||||
@@ -377,6 +378,14 @@
|
||||
|
||||
private void GoBack() => NavigationManager.NavigateTo("/design/external-systems");
|
||||
|
||||
/// <summary>Cancels an in-flight Test Run when the component is torn down.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_runCts?.Cancel();
|
||||
_runCts?.Dispose();
|
||||
_runCts = null;
|
||||
}
|
||||
|
||||
private void ToggleTestRunPanel() => _showTestRun = !_showTestRun;
|
||||
|
||||
private async Task RunInSandboxAsync()
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
@inject ScriptAnalysis.ScriptAnalysisService AnalysisService
|
||||
@inject AuthenticationStateProvider AuthStateProvider
|
||||
@inject NavigationManager NavigationManager
|
||||
@implements IDisposable
|
||||
|
||||
<div class="container-fluid mt-3">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
@@ -241,6 +242,14 @@
|
||||
NavigationManager.NavigateTo("/design/shared-scripts");
|
||||
}
|
||||
|
||||
/// <summary>Cancels an in-flight Test Run when the component is torn down.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_runCts?.Cancel();
|
||||
_runCts?.Dispose();
|
||||
_runCts = null;
|
||||
}
|
||||
|
||||
private void CheckCompilation()
|
||||
{
|
||||
var syntaxError = ValidateSyntaxLocally(_formCode);
|
||||
|
||||
Reference in New Issue
Block a user