Stream CDN artifacts in coarse durable windows

This commit is contained in:
Meta Vens 2026-07-19 20:29:07 +01:00
commit ff89a5f007
3 changed files with 30 additions and 7 deletions

View file

@ -42,7 +42,7 @@ namespace GameCult.Mesh
public sealed class CultMeshCdnPackOptions
{
/// <summary>Default CDN chunk size.</summary>
public const int DefaultChunkSizeBytes = 256 * 1024;
public const int DefaultChunkSizeBytes = 4 * 1024 * 1024;
/// <summary>Maximum bytes per content chunk.</summary>
public int ChunkSizeBytes { get; set; } = DefaultChunkSizeBytes;

View file

@ -263,16 +263,37 @@ namespace GameCult.Mesh
{
await pending.Copy.ConfigureAwait(false);
verified.Add(pending.Item.Index);
await SaveStateAsync(contentHash, fingerprint, manifest.SizeBytes, verified, stateKey).ConfigureAwait(false);
await SaveStateAsync(
contentHash,
fingerprint,
manifest.SizeBytes,
verified,
stateKey,
flush: false).ConfigureAwait(false);
}
await _stateCache.FlushAsync().ConfigureAwait(false);
}
catch
{
foreach (var pending in window)
{
try { await pending.Copy.ConfigureAwait(false); }
try
{
await pending.Copy.ConfigureAwait(false);
if (verified.Add(pending.Item.Index))
{
await SaveStateAsync(
contentHash,
fingerprint,
manifest.SizeBytes,
verified,
stateKey,
flush: false).ConfigureAwait(false);
}
}
catch { }
}
await _stateCache.FlushAsync().ConfigureAwait(false);
throw;
}
}
@ -450,7 +471,8 @@ namespace GameCult.Mesh
string fingerprint,
long sizeBytes,
HashSet<int> verified,
CultRecordKey stateKey)
CultRecordKey stateKey,
bool flush)
{
var state = new CultMeshContentTransferStateDocument
{
@ -461,7 +483,7 @@ namespace GameCult.Mesh
UpdatedAtUtc = DateTimeOffset.UtcNow.ToString("O", CultureInfo.InvariantCulture)
};
await _stateCache.UpsertAsync(typeof(CultMeshContentTransferStateDocument), state, stateKey).ConfigureAwait(false);
await _stateCache.FlushAsync().ConfigureAwait(false);
if (flush) await _stateCache.FlushAsync().ConfigureAwait(false);
}
private static CultRecordKey StateKey(string contentHash) => new CultRecordKey("mesh:content-transfer:" + contentHash);

View file

@ -192,7 +192,7 @@ public sealed class CultMeshContentTransferTests
}
[Test]
public async Task FetchAsync_ObservesRemainingWindowTasksWhenEarlierFetchFails()
public async Task FetchAsync_CheckpointsVerifiedWindowPeersWhenEarlierFetchFails()
{
var artifact = Artifact("failed-window", 2);
using var cache = Cache();
@ -210,7 +210,8 @@ public sealed class CultMeshContentTransferTests
.Should().ThrowAsync<InvalidDataException>();
provider.ActiveRequests.Should().Be(0, "the failed window must observe every task before returning");
cache.Get<CultMeshContentTransferStateDocument>(StateKey(artifact.Manifest)).Should().BeNull();
cache.Get<CultMeshContentTransferStateDocument>(StateKey(artifact.Manifest))!
.VerifiedChunkIndexes.Should().Equal(1, 2);
File.Exists(Path.Combine(_directory, artifact.Manifest.ContentHash + ".body")).Should().BeFalse();
}