Retry failed Eve presentation candidates
This commit is contained in:
parent
47122fa53e
commit
da5bc22e16
3 changed files with 50 additions and 14 deletions
|
|
@ -73,6 +73,8 @@ namespace GameCult.Eve.UnityScene
|
|||
private bool _assetCatalogUpdateRunning;
|
||||
private long _surfaceAssetGeneration;
|
||||
private long _highestObservedBaseSurfaceVersion = -1;
|
||||
private long _activeBaseSurfaceCandidateVersion = -1;
|
||||
private long _activeBaseSurfaceCandidateGeneration = -1;
|
||||
private long _mountedBaseSurfaceVersion;
|
||||
private long _presentationBarrierVersion = -1;
|
||||
private long _lastQueuedEntityViewEpoch = -1;
|
||||
|
|
@ -911,7 +913,7 @@ namespace GameCult.Eve.UnityScene
|
|||
private void PublishBaseSurface(EveSurfaceDocument surface)
|
||||
{
|
||||
if (surface == null) throw new ArgumentNullException(nameof(surface));
|
||||
if (!TryObserveBaseSurfaceVersion(surface.Version))
|
||||
if (!TryBeginBaseSurfaceCandidate(surface.Version, out var generation))
|
||||
return;
|
||||
CancellationToken candidateToken;
|
||||
lock (_presentationFinalityGate)
|
||||
|
|
@ -921,7 +923,6 @@ namespace GameCult.Eve.UnityScene
|
|||
_surfaceAssetCandidateLifetime = CancellationTokenSource.CreateLinkedTokenSource(_lifetime.Token);
|
||||
candidateToken = _surfaceAssetCandidateLifetime.Token;
|
||||
}
|
||||
var generation = Interlocked.Increment(ref _surfaceAssetGeneration);
|
||||
if (!_bootstrapped)
|
||||
{
|
||||
_baseSurface = surface;
|
||||
|
|
@ -946,17 +947,36 @@ namespace GameCult.Eve.UnityScene
|
|||
_ = RefreshAssetsForSurfaceAsync(surface, source, generation, candidateToken);
|
||||
}
|
||||
|
||||
private bool TryObserveBaseSurfaceVersion(long version)
|
||||
private bool TryBeginBaseSurfaceCandidate(long version, out long generation)
|
||||
{
|
||||
lock (_presentationFinalityGate)
|
||||
{
|
||||
if (version <= _highestObservedBaseSurfaceVersion)
|
||||
generation = -1;
|
||||
if (version < _highestObservedBaseSurfaceVersion ||
|
||||
version <= _mountedBaseSurfaceVersion ||
|
||||
(version == _highestObservedBaseSurfaceVersion &&
|
||||
_activeBaseSurfaceCandidateVersion == version))
|
||||
return false;
|
||||
_highestObservedBaseSurfaceVersion = version;
|
||||
_highestObservedBaseSurfaceVersion = Math.Max(_highestObservedBaseSurfaceVersion, version);
|
||||
generation = Interlocked.Increment(ref _surfaceAssetGeneration);
|
||||
_activeBaseSurfaceCandidateVersion = version;
|
||||
_activeBaseSurfaceCandidateGeneration = generation;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void RetireFailedBaseSurfaceCandidate(long version, long generation)
|
||||
{
|
||||
lock (_presentationFinalityGate)
|
||||
{
|
||||
if (_activeBaseSurfaceCandidateVersion != version ||
|
||||
_activeBaseSurfaceCandidateGeneration != generation)
|
||||
return;
|
||||
_activeBaseSurfaceCandidateVersion = -1;
|
||||
_activeBaseSurfaceCandidateGeneration = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void PublishEmbeddedSurface(string recordKey, EveSurfaceDocument surface)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(recordKey))
|
||||
|
|
@ -1349,6 +1369,7 @@ namespace GameCult.Eve.UnityScene
|
|||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
RetireFailedBaseSurfaceCandidate(surface.Version, generation);
|
||||
_liveDocuments.Enqueue(error);
|
||||
}
|
||||
}
|
||||
|
|
@ -2110,6 +2131,11 @@ namespace GameCult.Eve.UnityScene
|
|||
lock (_presentationFinalityGate)
|
||||
{
|
||||
_mountedBaseSurfaceVersion = Math.Max(_mountedBaseSurfaceVersion, committedVersion);
|
||||
if (_activeBaseSurfaceCandidateVersion == committedVersion)
|
||||
{
|
||||
_activeBaseSurfaceCandidateVersion = -1;
|
||||
_activeBaseSurfaceCandidateGeneration = -1;
|
||||
}
|
||||
ready = _deferredTerminalReceipts.Values
|
||||
.Where(receipt => receipt.PresentationSurfaceVersion <= _mountedBaseSurfaceVersion)
|
||||
.ToArray();
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
presentationSurfaceVersion: presentationSurfaceVersion);
|
||||
|
||||
[Test]
|
||||
public void OlderObservedBaseVersionCannotSupersedeANewerCandidate()
|
||||
public void FailedNewestCandidateCanRetryWithoutAllowingAnOlderSurface()
|
||||
{
|
||||
using var transport = new EveUnityCultMeshLiveProviderTransport(
|
||||
"test-cache",
|
||||
|
|
@ -366,14 +366,24 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
"test.runtime",
|
||||
"test.provider",
|
||||
"test.surface");
|
||||
var observe = typeof(EveUnityCultMeshLiveProviderTransport).GetMethod(
|
||||
"TryObserveBaseSurfaceVersion",
|
||||
var begin = typeof(EveUnityCultMeshLiveProviderTransport).GetMethod(
|
||||
"TryBeginBaseSurfaceCandidate",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance)!;
|
||||
var retire = typeof(EveUnityCultMeshLiveProviderTransport).GetMethod(
|
||||
"RetireFailedBaseSurfaceCandidate",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance)!;
|
||||
var first = new object[] { 10L, -1L };
|
||||
var older = new object[] { 7L, -1L };
|
||||
var duplicate = new object[] { 10L, -1L };
|
||||
|
||||
Assert.That(observe.Invoke(transport, new object[] { 10L }), Is.True);
|
||||
Assert.That(observe.Invoke(transport, new object[] { 7L }), Is.False);
|
||||
Assert.That(observe.Invoke(transport, new object[] { 10L }), Is.False);
|
||||
Assert.That(observe.Invoke(transport, new object[] { 11L }), Is.True);
|
||||
Assert.That(begin.Invoke(transport, first), Is.True);
|
||||
Assert.That(begin.Invoke(transport, older), Is.False);
|
||||
Assert.That(begin.Invoke(transport, duplicate), Is.False);
|
||||
retire.Invoke(transport, new[] { first[0], first[1] });
|
||||
var retry = new object[] { 10L, -1L };
|
||||
Assert.That(begin.Invoke(transport, retry), Is.True);
|
||||
Assert.That((long)retry[1], Is.GreaterThan((long)first[1]));
|
||||
Assert.That(begin.Invoke(transport, new object[] { 9L, -1L }), Is.False);
|
||||
}
|
||||
|
||||
private static EveUnitySceneProviderSurfaceDocument SceneSurface(long version)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "org.gamecult.eve.unity-scene",
|
||||
"displayName": "Eve Unity Scene Lowering",
|
||||
"version": "0.3.132",
|
||||
"version": "0.3.133",
|
||||
"unity": "6000.0",
|
||||
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
|
||||
"dependencies": {
|
||||
|
|
|
|||
Reference in a new issue