test(historian): bounded-wait durability read; honest nondeterminism notes on the #491 controls
This commit is contained in:
+35
-1
@@ -1,3 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using FASTER.core;
|
||||
using Xunit;
|
||||
@@ -188,7 +189,10 @@ public sealed class FasterLogHistorizationOutboxTests : IDisposable
|
||||
{
|
||||
await writer.AppendBatchAsync([a, b, c], TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(new[] { a.Id, b.Id, c.Id }, ReadCommitted(dir));
|
||||
Guid[] committed = await ReadCommittedWhenVisibleAsync(
|
||||
dir, expected: 3, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(new[] { a.Id, b.Id, c.Id }, committed);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -196,6 +200,36 @@ public sealed class FasterLogHistorizationOutboxTests : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
// Bounded poll over ReadCommitted for the group-commit pin above. AppendBatchAsync's commit has
|
||||
// already returned by the time we look, but an INDEPENDENT FasterLog learns about it only by
|
||||
// re-reading the on-disk commit metadata — and how promptly that write becomes visible to a
|
||||
// second reader is a filesystem property, not a FasterLog guarantee (recorded as fragile on
|
||||
// macOS, where it is not on the Windows/Linux timescale). A single-shot read is therefore
|
||||
// timing-dependent and green partly by luck. Each attempt calls ReadCommitted, which builds a
|
||||
// FRESH device + FasterLog and so re-reads the metadata rather than reusing a stale view —
|
||||
// verified: a reader opened after a later commit does observe that commit.
|
||||
//
|
||||
// The bounded wait does NOT weaken the claim: the writer is never disposed during the poll (the
|
||||
// only other thing that could commit), and PerEntry mode runs no periodic-commit loop — so
|
||||
// anything that becomes visible inside the window was still made durable by AppendBatchAsync's
|
||||
// own group commit and nothing else. A missing commit stays missing for the whole 5 s and the
|
||||
// test still goes red.
|
||||
//
|
||||
// On timeout the last read is returned rather than thrown on, so the caller's Assert.Equal
|
||||
// reports the actual shortfall (which ids were durable) instead of a bare timeout message.
|
||||
private static async Task<Guid[]> ReadCommittedWhenVisibleAsync(string dir, int expected, CancellationToken ct)
|
||||
{
|
||||
var elapsed = Stopwatch.StartNew();
|
||||
Guid[] ids = ReadCommitted(dir);
|
||||
while (ids.Length < expected && elapsed.Elapsed < TimeSpan.FromSeconds(5))
|
||||
{
|
||||
await Task.Delay(25, ct);
|
||||
ids = ReadCommitted(dir);
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
// Opens an independent read-only FasterLog over the outbox's directory and returns the ids of
|
||||
// every record the writer has COMMITTED (BeginAddress .. CommittedUntilAddress). Uncommitted
|
||||
// enqueues sit past CommittedUntilAddress and are therefore invisible here — which is exactly
|
||||
|
||||
Reference in New Issue
Block a user