Stream CDN artifacts in coarse durable windows
This commit is contained in:
parent
c148d891c1
commit
ff89a5f007
3 changed files with 30 additions and 7 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue