fix(userdata): read user data through to the database #32
Reference in New Issue
Block a user
Delete Branch "benvin/userdata-cache"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The user data cache and the item's in-memory rows were both filled once per replica and never invalidated, so a pod serving a playback tick read its own stale resume position and wrote it back over the position another pod had just saved, silently losing resume points, played state, favourites and ratings.
Closes #13
DetermineNextEpisodecalls_userDataManager.GetUserData(user, episode/version)per item inside aWherepredicate and aforeachover versions, once per series inGetNextUpBatched; with the LRU cache gone this is now an unbatched DB round trip per candidate item per series on every Next Up request → prefetch/batch these likeLibraryManager.PrefetchUserDataandUserViewBuilderdo (e.g.GetUserDataBatchover specials + lastWatched + nextEpisode + all versions once perGetNextUpBatchedcall).PrefetchedUserDataadded to a public plugin-facing interface with no default implementation; breaks any externalIUserBaseItemComparerimplementation → give it a default interface implementation or document as a breaking change.SaveUserDatastill attaches the whole row asEntityState.Modifiedwith no concurrency token; two ticks landing on different replicas inside the same read-modify-write window can still silently clobber each other (this PR closes the stale-cache vector, not the general write race).itemOnB.UserData = await LoadUserDataAsync(...)setsBaseItem.UserData, whichUserDataManager.GetUserData/GetUserDataBatchno longer read (they query the DB directly); the line and its "holds the earlier row in memory" comments are vestigial and misstate what the test covers → drop the assignment or update the comment to reflect that coverage comes from the directGetUserDatacalls.Assert.Equal(3, batchReads)only exercises the defaultEnableResumable=false/EnableRewatching=falsepath; add cases withEnableRewatching=trueand specials present to cover the query-count claim across the flag space the production code actually branches on.