From 24c600c2b465a62a64e9f8f4ef2d0f9f97e5de92 Mon Sep 17 00:00:00 2001 From: Theaux Masquelier <43664045+Theauxm@users.noreply.github.com> Date: Fri, 27 Mar 2026 15:17:47 -0600 Subject: [PATCH] fix: use disposal-linked CancellationToken in dashboard dialogs RunTrainDialog and QueueTrainDialog used CancellationToken.None for database operations. If the dialog is disposed mid-operation (user navigates away), the DB calls now cancel instead of running to completion orphaned. --- .../Components/Dialogs/QueueTrainDialog.razor.cs | 16 +++++++++++----- .../Components/Dialogs/RunTrainDialog.razor.cs | 16 +++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Trax.Dashboard/Components/Dialogs/QueueTrainDialog.razor.cs b/src/Trax.Dashboard/Components/Dialogs/QueueTrainDialog.razor.cs index d5825de..8d662ee 100644 --- a/src/Trax.Dashboard/Components/Dialogs/QueueTrainDialog.razor.cs +++ b/src/Trax.Dashboard/Components/Dialogs/QueueTrainDialog.razor.cs @@ -13,8 +13,10 @@ namespace Trax.Dashboard.Components.Dialogs; -public partial class QueueTrainDialog +public partial class QueueTrainDialog : IDisposable { + private readonly CancellationTokenSource _cts = new(); + [Inject] private IDataContextProviderFactory DataContextFactory { get; set; } = default!; @@ -100,11 +102,9 @@ private async Task QueueTrain() } ); - using var dataContext = await DataContextFactory.CreateDbContextAsync( - CancellationToken.None - ); + using var dataContext = await DataContextFactory.CreateDbContextAsync(_cts.Token); await dataContext.Track(entry); - await dataContext.SaveChanges(CancellationToken.None); + await dataContext.SaveChanges(_cts.Token); DialogService.Close(); Navigation.NavigateTo($"trax/data/work-queue/{entry.Id}"); @@ -217,4 +217,10 @@ private static string GetPlaceholder(Type type) => "yyyy-MM-dd HH:mm:ss", _ => $"Enter {type.Name}", }; + + public void Dispose() + { + _cts.Cancel(); + _cts.Dispose(); + } } diff --git a/src/Trax.Dashboard/Components/Dialogs/RunTrainDialog.razor.cs b/src/Trax.Dashboard/Components/Dialogs/RunTrainDialog.razor.cs index a721f6a..bea72c2 100644 --- a/src/Trax.Dashboard/Components/Dialogs/RunTrainDialog.razor.cs +++ b/src/Trax.Dashboard/Components/Dialogs/RunTrainDialog.razor.cs @@ -13,8 +13,10 @@ namespace Trax.Dashboard.Components.Dialogs; -public partial class RunTrainDialog +public partial class RunTrainDialog : IDisposable { + private readonly CancellationTokenSource _cts = new(); + [Inject] private IDataContextProviderFactory DataContextFactory { get; set; } = default!; @@ -95,11 +97,9 @@ private async Task EnqueueTrain() } ); - using var dataContext = await DataContextFactory.CreateDbContextAsync( - CancellationToken.None - ); + using var dataContext = await DataContextFactory.CreateDbContextAsync(_cts.Token); await dataContext.Track(metadata); - await dataContext.SaveChanges(CancellationToken.None); + await dataContext.SaveChanges(_cts.Token); await JobSubmitter.EnqueueAsync(metadata.Id, input); @@ -214,4 +214,10 @@ private static string GetPlaceholder(Type type) => "yyyy-MM-dd HH:mm:ss", _ => $"Enter {type.Name}", }; + + public void Dispose() + { + _cts.Cancel(); + _cts.Dispose(); + } }