From b8520dd854afa28d2ee3d67636feea595eb8c0e1 Mon Sep 17 00:00:00 2001 From: halgari Date: Thu, 8 Aug 2024 12:36:29 -0600 Subject: [PATCH] Fix refcount bug --- .../Query/ObservableDatoms.cs | 2 +- ....RefCountWorksWithObservables.verified.txt | 5 ++ tests/NexusMods.MnemonicDB.Tests/DbTests.cs | 46 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/NexusMods.MnemonicDB.Tests/DbTests.RefCountWorksWithObservables.verified.txt diff --git a/src/NexusMods.MnemonicDB.Abstractions/Query/ObservableDatoms.cs b/src/NexusMods.MnemonicDB.Abstractions/Query/ObservableDatoms.cs index 6ce42cf..8683ff9 100644 --- a/src/NexusMods.MnemonicDB.Abstractions/Query/ObservableDatoms.cs +++ b/src/NexusMods.MnemonicDB.Abstractions/Query/ObservableDatoms.cs @@ -49,7 +49,7 @@ public static IObservable> ObserveDatoms(this IConnection conn { lock (set) { - if (rev.BasisTxId <= lastTxId) + if (rev.BasisTxId <= lastTxId && idx != 0) return ChangeSet.Empty; lastTxId = rev.BasisTxId; diff --git a/tests/NexusMods.MnemonicDB.Tests/DbTests.RefCountWorksWithObservables.verified.txt b/tests/NexusMods.MnemonicDB.Tests/DbTests.RefCountWorksWithObservables.verified.txt new file mode 100644 index 0000000..d877f83 --- /dev/null +++ b/tests/NexusMods.MnemonicDB.Tests/DbTests.RefCountWorksWithObservables.verified.txt @@ -0,0 +1,5 @@ +[ + Test Mod, + Test Mod 2, + Test Mod 3 +] \ No newline at end of file diff --git a/tests/NexusMods.MnemonicDB.Tests/DbTests.cs b/tests/NexusMods.MnemonicDB.Tests/DbTests.cs index c4bdf90..d4ab760 100644 --- a/tests/NexusMods.MnemonicDB.Tests/DbTests.cs +++ b/tests/NexusMods.MnemonicDB.Tests/DbTests.cs @@ -911,4 +911,50 @@ public async Task CollectionAttributesAreSupportedOnModels() modRO.Tags.Should().BeEquivalentTo(["A", "B", "C"]); } + + /// + /// Tests a bug experienced in the app, when RefCount is used with ObserveDatoms, if the last subscription + /// is disposed, and then another subscriber attaches, an exception would be thrown. This test ensures that + /// this behavior works correctly. + /// + [Fact] + public async Task RefCountWorksWithObservables() + { + var tx = Connection.BeginTransaction(); + var mod = new Mod.New(tx) + { + Name = "Test Mod", + Source = new Uri("http://test.com"), + LoadoutId = EntityId.From(0) + }; + var result = await tx.Commit(); + + var modRO = result.Remap(mod); + + var refObs = Mod.Observe(Connection, modRO.Id) + .Replay(1) + .RefCount(); + + List mods = []; + + var firstDisp = refObs.Subscribe(mods.Add); + + { + var tx2 = Connection.BeginTransaction(); + tx2.Add(modRO.Id, Mod.Name, "Test Mod 2"); + await tx2.Commit(); + } + + firstDisp.Dispose(); + + var secondDisp = refObs.Subscribe(mods.Add); + + { + var tx2 = Connection.BeginTransaction(); + tx2.Add(modRO.Id, Mod.Name, "Test Mod 3"); + await tx2.Commit(); + } + + await Verify(mods.Distinct().Select(m => m.Name)); + } }