Get full library in LibrarySizeChanged event and pass as EventArgs

There are multiple subscribers to LibraryCommands.LibrarySizeChanged, and each one calls GetLibrary_Flat_NoTracking(). Passing the full library as an event argument speeds up all operations which happen after the library size changes.

Fix initial backup counts
This commit is contained in:
Michael Bucari-Tovo 2025-02-27 12:05:51 -07:00
parent 2a25b7e0ad
commit 2d6120f0c4
9 changed files with 44 additions and 25 deletions

View File

@ -279,8 +279,11 @@ namespace AppScaffolding
private static void wireUpSystemEvents(Configuration configuration) private static void wireUpSystemEvents(Configuration configuration)
{ {
LibraryCommands.LibrarySizeChanged += (_, __) => SearchEngineCommands.FullReIndex(); LibraryCommands.LibrarySizeChanged += (object _, List<DataLayer.LibraryBook> libraryBooks)
LibraryCommands.BookUserDefinedItemCommitted += (_, books) => SearchEngineCommands.UpdateBooks(books); => SearchEngineCommands.FullReIndex(libraryBooks);
LibraryCommands.BookUserDefinedItemCommitted += (_, books)
=> SearchEngineCommands.UpdateBooks(books);
} }
public static UpgradeProperties GetLatestRelease() public static UpgradeProperties GetLatestRelease()

View File

@ -445,10 +445,14 @@ namespace ApplicationServices
#endregion #endregion
// call this whenever books are added or removed from library // call this whenever books are added or removed from library
private static void finalizeLibrarySizeChange() => LibrarySizeChanged?.Invoke(null, null); private static void finalizeLibrarySizeChange()
{
var library = DbContexts.GetLibrary_Flat_NoTracking(includeParents: true);
LibrarySizeChanged?.Invoke(null, library);
}
/// <summary>Occurs when the size of the library changes. ie: books are added or removed</summary> /// <summary>Occurs when the size of the library changes. ie: books are added or removed</summary>
public static event EventHandler LibrarySizeChanged; public static event EventHandler<List<LibraryBook>> LibrarySizeChanged;
/// <summary> /// <summary>
/// Occurs when the size of the library does not change but book(s) details do. Especially when <see cref="UserDefinedItem.Tags"/>, <see cref="UserDefinedItem.BookStatus"/>, or <see cref="UserDefinedItem.PdfStatus"/> changed values are successfully persisted. /// Occurs when the size of the library does not change but book(s) details do. Especially when <see cref="UserDefinedItem.Tags"/>, <see cref="UserDefinedItem.BookStatus"/>, or <see cref="UserDefinedItem.PdfStatus"/> changed values are successfully persisted.
@ -600,6 +604,7 @@ namespace ApplicationServices
var results = libraryBooks var results = libraryBooks
.AsParallel() .AsParallel()
.WithoutParents()
.Select(lb => new { absent = lb.AbsentFromLastScan, status = Liberated_Status(lb.Book) }) .Select(lb => new { absent = lb.AbsentFromLastScan, status = Liberated_Status(lb.Book) })
.ToList(); .ToList();

View File

@ -48,6 +48,8 @@ namespace ApplicationServices
} }
public static void FullReIndex() => performSafeCommand(fullReIndex); public static void FullReIndex() => performSafeCommand(fullReIndex);
public static void FullReIndex(List<LibraryBook> libraryBooks)
=> performSafeCommand(se => fullReIndex(se, libraryBooks.WithoutParents()));
internal static void UpdateUserDefinedItems(LibraryBook book) => performSafeCommand(e => internal static void UpdateUserDefinedItems(LibraryBook book) => performSafeCommand(e =>
{ {
@ -94,8 +96,11 @@ namespace ApplicationServices
private static void fullReIndex(SearchEngine engine) private static void fullReIndex(SearchEngine engine)
{ {
var library = DbContexts.GetLibrary_Flat_NoTracking(); var library = DbContexts.GetLibrary_Flat_NoTracking();
engine.CreateNewIndex(library); fullReIndex(engine, library);
} }
private static void fullReIndex(SearchEngine engine, IEnumerable<LibraryBook> libraryBooks)
=> engine.CreateNewIndex(libraryBooks);
#endregion #endregion
} }
} }

View File

@ -44,6 +44,10 @@ namespace DataLayer
public static bool IsEpisodeParent(this Book book) public static bool IsEpisodeParent(this Book book)
=> book.ContentType is ContentType.Parent; => book.ContentType is ContentType.Parent;
public static IEnumerable<LibraryBook> WithoutParents(this IEnumerable<LibraryBook> libraryBooks)
=> libraryBooks.Where(lb => !lb.Book.IsEpisodeParent());
public static bool HasLiberated(this Book book) public static bool HasLiberated(this Book book)
=> book.UserDefinedItem.BookStatus is LiberatedStatus.Liberated || => book.UserDefinedItem.BookStatus is LiberatedStatus.Liberated ||
book.UserDefinedItem.PdfStatus is not null and LiberatedStatus.Liberated; book.UserDefinedItem.PdfStatus is not null and LiberatedStatus.Liberated;

View File

@ -44,16 +44,18 @@ namespace LibationAvalonia.ViewModels
private void Configure_BackupCounts() private void Configure_BackupCounts()
{ {
MainWindow.LibraryLoaded += (_, e) => setBackupCounts(e.Where(l => !l.Book.IsEpisodeParent())); LibraryCommands.LibrarySizeChanged += async (object _, List<LibraryBook> libraryBooks)
LibraryCommands.LibrarySizeChanged += (_,_) => setBackupCounts(); => await SetBackupCountsAsync(libraryBooks);
LibraryCommands.BookUserDefinedItemCommitted += (_, _) => setBackupCounts();
//Pass null to the setup count to get the whole library.
LibraryCommands.BookUserDefinedItemCommitted += async (_, _)
=> await SetBackupCountsAsync(null);
} }
private async void setBackupCounts(IEnumerable<LibraryBook> libraryBooks = null) public async Task SetBackupCountsAsync(IEnumerable<LibraryBook> libraryBooks)
{ {
if (updateCountsTask?.IsCompleted ?? true) if (updateCountsTask?.IsCompleted ?? true)
{ {
libraryBooks ??= DbContexts.GetLibrary_Flat_NoTracking();
updateCountsTask = Task.Run(() => LibraryCommands.GetCounts(libraryBooks)); updateCountsTask = Task.Run(() => LibraryCommands.GetCounts(libraryBooks));
var stats = await updateCountsTask; var stats = await updateCountsTask;
await Dispatcher.UIThread.InvokeAsync(() => LibraryStats = stats); await Dispatcher.UIThread.InvokeAsync(() => LibraryStats = stats);

View File

@ -1,7 +1,9 @@
using ApplicationServices; using ApplicationServices;
using DataLayer;
using LibationAvalonia.Views; using LibationAvalonia.Views;
using LibationFileManager; using LibationFileManager;
using ReactiveUI; using ReactiveUI;
using System.Collections.Generic;
namespace LibationAvalonia.ViewModels namespace LibationAvalonia.ViewModels
{ {
@ -34,9 +36,8 @@ namespace LibationAvalonia.ViewModels
Configure_VisibleBooks(); Configure_VisibleBooks();
} }
private async void LibraryCommands_LibrarySizeChanged(object sender, System.EventArgs e) private async void LibraryCommands_LibrarySizeChanged(object sender, List<LibraryBook> fullLibrary)
{ {
var fullLibrary = await System.Threading.Tasks.Task.Run(() => DbContexts.GetLibrary_Flat_NoTracking(includeParents: true));
await ProductsDisplay.UpdateGridAsync(fullLibrary); await ProductsDisplay.UpdateGridAsync(fullLibrary);
} }

View File

@ -13,7 +13,6 @@ namespace LibationAvalonia.Views
{ {
public partial class MainWindow : ReactiveWindow<MainVM> public partial class MainWindow : ReactiveWindow<MainVM>
{ {
public event EventHandler<List<LibraryBook>> LibraryLoaded;
public MainWindow() public MainWindow()
{ {
DataContext = new MainVM(this); DataContext = new MainVM(this);
@ -66,6 +65,7 @@ namespace LibationAvalonia.Views
if (QuickFilters.UseDefault) if (QuickFilters.UseDefault)
await ViewModel.PerformFilter(QuickFilters.Filters.FirstOrDefault()); await ViewModel.PerformFilter(QuickFilters.Filters.FirstOrDefault());
await ViewModel.SetBackupCountsAsync(initialLibrary);
await ViewModel.ProductsDisplay.BindToGridAsync(initialLibrary); await ViewModel.ProductsDisplay.BindToGridAsync(initialLibrary);
} }

View File

@ -17,7 +17,9 @@ namespace LibationWinForms
beginPdfBackupsToolStripMenuItem.Format(0); beginPdfBackupsToolStripMenuItem.Format(0);
LibraryCommands.LibrarySizeChanged += setBackupCounts; LibraryCommands.LibrarySizeChanged += setBackupCounts;
LibraryCommands.BookUserDefinedItemCommitted += setBackupCounts; //Pass null to the runner to get the whole library.
LibraryCommands.BookUserDefinedItemCommitted += (_, _)
=> setBackupCounts(null, null);
updateCountsBw.DoWork += UpdateCountsBw_DoWork; updateCountsBw.DoWork += UpdateCountsBw_DoWork;
updateCountsBw.RunWorkerCompleted += exportMenuEnable; updateCountsBw.RunWorkerCompleted += exportMenuEnable;
@ -28,12 +30,12 @@ namespace LibationWinForms
private bool runBackupCountsAgain; private bool runBackupCountsAgain;
private void setBackupCounts(object _, object __) private void setBackupCounts(object _, List<LibraryBook> libraryBooks)
{ {
runBackupCountsAgain = true; runBackupCountsAgain = true;
if (!updateCountsBw.IsBusy) if (!updateCountsBw.IsBusy)
updateCountsBw.RunWorkerAsync(); updateCountsBw.RunWorkerAsync(libraryBooks);
} }
private void UpdateCountsBw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) private void UpdateCountsBw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
@ -41,11 +43,7 @@ namespace LibationWinForms
while (runBackupCountsAgain) while (runBackupCountsAgain)
{ {
runBackupCountsAgain = false; runBackupCountsAgain = false;
e.Result = LibraryCommands.GetCounts(e.Argument as IEnumerable<LibraryBook>);
if (e.Argument is not IEnumerable<LibraryBook> lbs)
lbs = DbContexts.GetLibrary_Flat_NoTracking();
e.Result = LibraryCommands.GetCounts(lbs);
} }
} }

View File

@ -52,7 +52,8 @@ namespace LibationWinForms
// Configure_Grid(); // since it's just this, can keep here. If it needs more, then give grid it's own 'partial class Form1' // Configure_Grid(); // since it's just this, can keep here. If it needs more, then give grid it's own 'partial class Form1'
{ {
LibraryCommands.LibrarySizeChanged += (_, __) => Invoke(() => productsDisplay.DisplayAsync()); LibraryCommands.LibrarySizeChanged += (object _, List<LibraryBook> fullLibrary)
=> Invoke(() => productsDisplay.DisplayAsync(fullLibrary));
} }
Shown += Form1_Shown; Shown += Form1_Shown;
} }
@ -75,7 +76,7 @@ namespace LibationWinForms
public async Task InitLibraryAsync(List<LibraryBook> libraryBooks) public async Task InitLibraryAsync(List<LibraryBook> libraryBooks)
{ {
runBackupCountsAgain = true; runBackupCountsAgain = true;
updateCountsBw.RunWorkerAsync(libraryBooks.Where(b => !b.Book.IsEpisodeParent())); updateCountsBw.RunWorkerAsync(libraryBooks);
await productsDisplay.DisplayAsync(libraryBooks); await productsDisplay.DisplayAsync(libraryBooks);
} }