perf(streaming): cursor publication across frame budgets

This commit is contained in:
Erik 2026-07-24 19:10:18 +02:00
parent bb16f74fd4
commit 98f1ac8934
32 changed files with 2215 additions and 823 deletions

View file

@ -370,7 +370,11 @@ public sealed class StreamingController : IStreamingFrameBackend
// the desired-tier snapshot below is computed. Otherwise a landblock
// that becomes spatially resident during convergence is absent from
// the reconfiguration mutation ledger.
ConvergePendingPublications();
if (!ConvergePendingPublications())
{
_deferredRadiiRequest = (nearRadius, farRadius);
return;
}
if (_collapsed || _region is null)
{
@ -490,6 +494,12 @@ public sealed class StreamingController : IStreamingFrameBackend
_presentation.GetPendingPublicationResults();
if (pending.Count == 0)
return true;
if (_activeWorkMeter is null)
{
// Settings/native callbacks may request policy changes between
// frames, but publication remains owned by the frame-scoped meter.
return false;
}
try
{
@ -497,15 +507,14 @@ public sealed class StreamingController : IStreamingFrameBackend
for (int i = 0; i < pending.Count; i++)
{
LandblockStreamResult result = pending[i];
if (!TryObserveResultOperation(
result,
"publication-retry",
() => _presentation.ResumePublication(result),
ensureProgress: !progressed))
{
LandblockPublicationAdvance advance =
_presentation.ResumePublication(
result,
_activeWorkMeter,
ensureProgress: !progressed);
progressed |= advance.Progressed;
if (!advance.Completed)
return false;
}
progressed = true;
}
return true;
}
@ -1487,23 +1496,16 @@ public sealed class StreamingController : IStreamingFrameBackend
StreamingQueuedCompletion work = completion
?? throw new InvalidOperationException(
"The completion queue returned a null head.");
StreamingWorkCost executionCost =
IsStaleGeneration(work.Result)
? default
: work.ExecutionCost;
StreamingWorkAdmission admission = meter.TryReserve(
executionCost,
$"execute-{work.Priority}",
ensureProgress: !executed);
if (admission == StreamingWorkAdmission.Yielded)
break;
try
{
ApplyResult(work.Result);
LandblockPublicationAdvance advance = ApplyResult(
work,
meter,
ensureProgress: !executed);
executed |= advance.Progressed;
if (!advance.Completed)
break;
_completionQueue.RemoveHead(work);
meter.Complete();
executed = true;
}
catch
{
@ -1512,7 +1514,6 @@ public sealed class StreamingController : IStreamingFrameBackend
// receipt cannot safely replay, so consume only that result.
if (!_presentation.HasPendingPublication(work.Result))
_completionQueue.RemoveHead(work);
meter.Fail();
throw;
}
}
@ -1625,39 +1626,24 @@ public sealed class StreamingController : IStreamingFrameBackend
};
}
private bool TryObserveResultOperation(
LandblockStreamResult result,
private static LandblockPublicationAdvance RunSimpleResultOperation(
StreamingWorkMeter meter,
string stage,
Action operation,
StreamingWorkCost? knownCost = null,
bool ensureProgress = false)
bool ensureProgress,
Action operation)
{
StreamingWorkMeter? meter = _activeWorkMeter;
if (meter is null)
{
operation();
return true;
}
StreamingWorkCost aggregate = knownCost
?? LandblockStreamResultCost.Estimate(result).Work;
StreamingWorkCost cost = new(
EntityOperations: aggregate.EntityOperations,
GpuUploadBytes: aggregate.GpuUploadBytes,
GlRetireOperations:
result is LandblockStreamResult.Unloaded ? 1 : 0);
StreamingWorkAdmission admission = meter.TryReserve(
cost,
default,
stage,
ensureProgress);
if (admission == StreamingWorkAdmission.Yielded)
return false;
return new LandblockPublicationAdvance(false, false);
try
{
operation();
meter.Complete();
return true;
return new LandblockPublicationAdvance(true, true);
}
catch
{
@ -1671,13 +1657,22 @@ public sealed class StreamingController : IStreamingFrameBackend
/// effects: terrain upload, GPU state, and the re-hydration callback.
/// All priority queues route through this one publication path.
/// </summary>
private void ApplyResult(LandblockStreamResult result)
private LandblockPublicationAdvance ApplyResult(
StreamingQueuedCompletion work,
StreamingWorkMeter meter,
bool ensureProgress)
{
LandblockStreamResult result = work.Result;
if (_presentation.HasPendingPublication(result))
{
_presentation.ResumePublication(result);
ReconcileCompletedPendingPublication(result.LandblockId);
return;
LandblockPublicationAdvance resumed =
_presentation.ResumePublication(
result,
meter,
ensureProgress);
if (resumed.Completed)
ReconcileCompletedPendingPublication(result.LandblockId);
return resumed;
}
if (IsStaleGeneration(result))
@ -1685,7 +1680,11 @@ public sealed class StreamingController : IStreamingFrameBackend
// A worker can finish one old load/unload after a hard recenter.
// Landblock id membership cannot distinguish overlapping windows;
// generation is the logical streaming incarnation boundary.
return;
return RunSimpleResultOperation(
meter,
"execute-stale-generation",
ensureProgress,
static () => { });
}
if (result is LandblockStreamResult.Unloaded
@ -1695,7 +1694,11 @@ public sealed class StreamingController : IStreamingFrameBackend
// rapid away->back can therefore re-own an id while its same-
// generation unload is already in the worker outbox. Current
// region ownership wins; the old unload must not tear it down.
return;
return RunSimpleResultOperation(
meter,
"execute-reowned-unload",
ensureProgress,
static () => { });
}
if (result is LandblockStreamResult.Loaded
@ -1707,7 +1710,11 @@ public sealed class StreamingController : IStreamingFrameBackend
// A hard recenter/collapse can leave one worker job already in
// flight. Its completion belongs to the old region and must not
// resurrect a landblock the new StreamingRegion never owns.
return;
return RunSimpleResultOperation(
meter,
"execute-undesired-load",
ensureProgress,
static () => { });
}
bool isNearCompletion = result is LandblockStreamResult.Promoted
@ -1722,7 +1729,11 @@ public sealed class StreamingController : IStreamingFrameBackend
// high-priority jobs. Publication is idempotent at this owner:
// never append statics, replay defaults, or reapply the complete
// Near transaction to an already-Near landblock.
return;
return RunSimpleResultOperation(
meter,
"execute-duplicate-near",
ensureProgress,
static () => { });
}
if (desiredTier == LandblockStreamTier.Far && isNearCompletion)
{
@ -1739,14 +1750,26 @@ public sealed class StreamingController : IStreamingFrameBackend
switch (result)
{
case LandblockStreamResult.Loaded loaded:
_presentation.PublishAsFar(loaded, loaded.Build, loaded.MeshData);
break;
return _presentation.PublishAsFar(
loaded,
loaded.Build,
loaded.MeshData,
meter,
ensureProgress);
case LandblockStreamResult.Promoted promoted:
_presentation.PublishAsFar(promoted, promoted.Build, promoted.MeshData);
break;
return _presentation.PublishAsFar(
promoted,
promoted.Build,
promoted.MeshData,
meter,
ensureProgress);
}
}
return;
return RunSimpleResultOperation(
meter,
"execute-already-far",
ensureProgress,
static () => { });
}
}
@ -1759,31 +1782,54 @@ public sealed class StreamingController : IStreamingFrameBackend
// This Far completion was queued before a newer Near load
// or promotion. Applying it would erase the entity/cell
// layer that now owns the landblock.
break;
return RunSimpleResultOperation(
meter,
"execute-stale-far-tier",
ensureProgress,
static () => { });
}
_presentation.PublishLoaded(loaded);
break;
return _presentation.PublishLoaded(
loaded,
work.Estimate,
meter,
ensureProgress);
case LandblockStreamResult.Promoted promoted:
// PromoteToNear carries a complete build and mesh because the
// streamer deliberately lets it supersede a queued LoadFar. If
// that Far job never started, publish this as the real Near
// landblock; if the base is already resident, merge only the
// Near layer so existing live projections retain identity.
_presentation.PublishPromoted(
return _presentation.PublishPromoted(
promoted,
mergeIntoExistingLandblock: _state.IsLoaded(promoted.LandblockId));
break;
mergeIntoExistingLandblock:
_state.IsLoaded(promoted.LandblockId),
work.Estimate,
meter,
ensureProgress);
case LandblockStreamResult.Unloaded unloaded:
_presentation.EnqueueFullRetirement(unloaded.LandblockId);
break;
return RunSimpleResultOperation(
meter,
"execute-unload",
ensureProgress,
() => _presentation.EnqueueFullRetirement(
unloaded.LandblockId));
case LandblockStreamResult.Failed failed:
Console.WriteLine(
$"streaming: load failed for 0x{failed.LandblockId:X8}: {failed.Error}");
break;
return RunSimpleResultOperation(
meter,
"execute-load-failure",
ensureProgress,
() => Console.WriteLine(
$"streaming: load failed for 0x{failed.LandblockId:X8}: {failed.Error}"));
case LandblockStreamResult.WorkerCrashed crashed:
Console.WriteLine(
$"streaming: worker CRASHED: {crashed.Error}");
break;
return RunSimpleResultOperation(
meter,
"execute-worker-crash",
ensureProgress,
() => Console.WriteLine(
$"streaming: worker CRASHED: {crashed.Error}"));
default:
throw new InvalidOperationException(
$"Unsupported streaming result {result.GetType().Name}.");
}
}