Fix Critical: IndexSystem lock races and TrackRepository.Update silent-create

- Replace object lock with SemaphoreSlim(1,1) on both DirectoryIndexDirectory
  and VaultIndexDirectory; SaveIndexAsync now executes inside the semaphore
  so mutate+persist is atomic
- ReloadIndexAsync acquires the semaphore before LoadIndexAsync so disk load
  and in-memory swap are atomic with respect to concurrent writes
- HasIndexEntry and GetEntryMetadata converted to async Task with WaitAsync;
  MediaVault.GetEntryAsync call sites updated accordingly
- TrackRepository.Update throws InvalidOperationException when Id not found
  instead of silently calling Create; service layer catches and wraps as fail result
This commit is contained in:
Daniel Harvey
2026-05-17 11:24:50 -04:00
parent 56d15027e4
commit 4a0c17c318
6 changed files with 57 additions and 31 deletions
@@ -64,11 +64,11 @@ public abstract class MediaVault : VaultIndexDirectory
var vaultType = MediaVaultTypeMap.GetVaultType<T>();
// Use thread-safe method from VaultIndexDirectory
if (!HasIndexEntry(entryId))
if (!await HasIndexEntry(entryId))
return null;
// Use thread-safe metadata retrieval
var metaData = GetEntryMetadata(entryId);
var metaData = await GetEntryMetadata(entryId);
if (metaData == null)
return null;