feat(runtime): freeze initial placement inbound admission
This commit is contained in:
parent
9d601817b8
commit
30012361e1
9 changed files with 2506 additions and 323 deletions
|
|
@ -30,11 +30,14 @@ internal readonly record struct RuntimeInitialCreateResidenceLease(
|
|||
RuntimeInitialCreateResidenceToken Token,
|
||||
RuntimeAuthoritativePositionRoute Route,
|
||||
RuntimeEntityPlacementToken Placement,
|
||||
WorldSession.EntitySpawn InitialCreate,
|
||||
ImmutableArray<RuntimeInitialCreateResidenceContinuation> Continuations)
|
||||
{
|
||||
internal bool IsValid => Token.IsValid
|
||||
&& Route.Accepted
|
||||
&& Route.Authority.Entity == Token.Entity
|
||||
&& InitialCreate.Guid != 0u
|
||||
&& InitialCreate.InstanceSequence == Token.Entity.Incarnation
|
||||
&& !Continuations.IsDefault
|
||||
&& HasValidContinuationChain()
|
||||
&& (!Route.PerformsSetPosition
|
||||
|
|
@ -43,7 +46,7 @@ internal readonly record struct RuntimeInitialCreateResidenceLease(
|
|||
|
||||
private bool HasValidContinuationChain()
|
||||
{
|
||||
ushort previousTeleport = Route.Authority.AcceptedTeleportSequence;
|
||||
uint ownerGuid = InitialCreate.Guid;
|
||||
for (int index = 0; index < Continuations.Length; index++)
|
||||
{
|
||||
RuntimeInitialCreateResidenceContinuation continuation =
|
||||
|
|
@ -51,52 +54,291 @@ internal readonly record struct RuntimeInitialCreateResidenceLease(
|
|||
if (!continuation.IsValid
|
||||
|| continuation.Sequence != (ulong)index + 1UL
|
||||
|| continuation.InstanceSequence != Token.Entity.Incarnation
|
||||
|| continuation.PositionAuthorityVersion
|
||||
!= Token.PositionAuthorityVersion
|
||||
|| continuation.PreviousTeleportSequence
|
||||
!= previousTeleport)
|
||||
|| continuation.Actions.Any(
|
||||
action => action.OwnerGuid != ownerGuid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
previousTeleport = continuation.AcceptedTeleportSequence;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal enum RuntimeInitialCreateContinuationKind : byte
|
||||
{
|
||||
SameIncarnationCreate,
|
||||
ObjDesc,
|
||||
Parent,
|
||||
Pickup,
|
||||
Position,
|
||||
Movement,
|
||||
State,
|
||||
Vector,
|
||||
}
|
||||
|
||||
internal enum RuntimeInitialCreateTailActionKind : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Isolated AP-119 compatibility behavior. Retail's equal-generation
|
||||
/// Create tail starts at ObjDesc and does not call set_description again.
|
||||
/// </summary>
|
||||
PreTailDescriptionAdaptation,
|
||||
ObjDesc,
|
||||
CreateParent,
|
||||
Parent,
|
||||
Pickup,
|
||||
Position,
|
||||
Movement,
|
||||
State,
|
||||
Vector,
|
||||
WeenieDescription,
|
||||
ResidentCellCleanup,
|
||||
}
|
||||
|
||||
internal readonly record struct RuntimeInitialCreateTailAction(
|
||||
RuntimeInitialCreateTailActionKind Kind,
|
||||
uint OwnerGuid,
|
||||
PhysicsSpawnData? Description = null,
|
||||
ObjDescEvent.Parsed? ObjDesc = null,
|
||||
CreateParentUpdate? CreateParent = null,
|
||||
ParentEvent.Parsed? Parent = null,
|
||||
PickupEvent.Parsed? Pickup = null,
|
||||
WorldSession.EntityPositionUpdate? Position = null,
|
||||
WorldSession.EntityMotionUpdate? Movement = null,
|
||||
SetState.Parsed? State = null,
|
||||
VectorUpdate.Parsed? Vector = null,
|
||||
WorldSession.EntitySpawn? WeenieDescription = null,
|
||||
RuntimeAcceptedPositionSource PositionSource =
|
||||
RuntimeAcceptedPositionSource.Unknown,
|
||||
PositionTimestampDisposition PositionDisposition =
|
||||
PositionTimestampDisposition.Rejected,
|
||||
ushort PreviousTeleportSequence = 0,
|
||||
AcceptedPhysicsTimestamps AcceptedTimestamps = default,
|
||||
bool AppliesMovementPayload = false,
|
||||
bool RetainMovementPayload = true,
|
||||
bool HasTimestampMutation = false)
|
||||
{
|
||||
internal bool IsStructurallyValid => HasExclusivePayload()
|
||||
&& Kind switch
|
||||
{
|
||||
RuntimeInitialCreateTailActionKind.PreTailDescriptionAdaptation =>
|
||||
Description is not null,
|
||||
RuntimeInitialCreateTailActionKind.ObjDesc => ObjDesc is { } objDesc
|
||||
&& objDesc.Guid == OwnerGuid,
|
||||
RuntimeInitialCreateTailActionKind.CreateParent =>
|
||||
CreateParent is { } createParent
|
||||
&& createParent.ChildGuid == OwnerGuid,
|
||||
RuntimeInitialCreateTailActionKind.Parent => Parent is { } parent
|
||||
&& parent.ChildGuid == OwnerGuid,
|
||||
RuntimeInitialCreateTailActionKind.Pickup => Pickup is { } pickup
|
||||
&& pickup.Guid == OwnerGuid,
|
||||
RuntimeInitialCreateTailActionKind.Position => Position is { } position
|
||||
&& position.Guid == OwnerGuid
|
||||
&& PositionSource is RuntimeAcceptedPositionSource.PositionEvent
|
||||
or RuntimeAcceptedPositionSource.SameIncarnationCreate
|
||||
&& (PositionDisposition is PositionTimestampDisposition.Apply
|
||||
or PositionTimestampDisposition.ForcePosition
|
||||
|| PositionDisposition is PositionTimestampDisposition.Rejected
|
||||
&& HasTimestampMutation),
|
||||
RuntimeInitialCreateTailActionKind.Movement => Movement is { } movement
|
||||
&& movement.Guid == OwnerGuid
|
||||
&& (AppliesMovementPayload || HasTimestampMutation),
|
||||
RuntimeInitialCreateTailActionKind.State => State is { } state
|
||||
&& state.Guid == OwnerGuid,
|
||||
RuntimeInitialCreateTailActionKind.Vector => Vector is { } vector
|
||||
&& vector.Guid == OwnerGuid,
|
||||
RuntimeInitialCreateTailActionKind.WeenieDescription =>
|
||||
WeenieDescription is { } weenie
|
||||
&& weenie.Guid == OwnerGuid,
|
||||
RuntimeInitialCreateTailActionKind.ResidentCellCleanup => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
internal bool MatchesInstance(ushort instanceSequence) => Kind switch
|
||||
{
|
||||
RuntimeInitialCreateTailActionKind.PreTailDescriptionAdaptation =>
|
||||
Description is { } description
|
||||
&& description.Timestamps.Instance == instanceSequence,
|
||||
RuntimeInitialCreateTailActionKind.ObjDesc =>
|
||||
ObjDesc is { } objDesc
|
||||
&& objDesc.InstanceSequence == instanceSequence,
|
||||
RuntimeInitialCreateTailActionKind.CreateParent =>
|
||||
CreateParent is { } createParent
|
||||
&& createParent.ChildInstanceSequence == instanceSequence,
|
||||
// ParentEvent carries only the parent's INSTANCE_TS. Acceptance
|
||||
// already exact-gated the child's current incarnation; preserve that
|
||||
// proof in AcceptedTimestamps for the later no-regate executor.
|
||||
RuntimeInitialCreateTailActionKind.Parent =>
|
||||
AcceptedTimestamps.Instance == instanceSequence,
|
||||
RuntimeInitialCreateTailActionKind.Pickup =>
|
||||
Pickup is { } pickup
|
||||
&& pickup.InstanceSequence == instanceSequence,
|
||||
RuntimeInitialCreateTailActionKind.Position =>
|
||||
Position is { } position
|
||||
&& position.InstanceSequence == instanceSequence,
|
||||
RuntimeInitialCreateTailActionKind.Movement =>
|
||||
Movement is { } movement
|
||||
&& movement.InstanceSequence == instanceSequence,
|
||||
RuntimeInitialCreateTailActionKind.State =>
|
||||
State is { } state
|
||||
&& state.InstanceSequence == instanceSequence,
|
||||
RuntimeInitialCreateTailActionKind.Vector =>
|
||||
Vector is { } vector
|
||||
&& vector.InstanceSequence == instanceSequence,
|
||||
RuntimeInitialCreateTailActionKind.WeenieDescription =>
|
||||
WeenieDescription is { } weenie
|
||||
&& weenie.InstanceSequence == instanceSequence,
|
||||
RuntimeInitialCreateTailActionKind.ResidentCellCleanup => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
private bool HasExclusivePayload()
|
||||
{
|
||||
int payloadCount = (Description is null ? 0 : 1)
|
||||
+ (ObjDesc is null ? 0 : 1)
|
||||
+ (CreateParent is null ? 0 : 1)
|
||||
+ (Parent is null ? 0 : 1)
|
||||
+ (Pickup is null ? 0 : 1)
|
||||
+ (Position is null ? 0 : 1)
|
||||
+ (Movement is null ? 0 : 1)
|
||||
+ (State is null ? 0 : 1)
|
||||
+ (Vector is null ? 0 : 1)
|
||||
+ (WeenieDescription is null ? 0 : 1);
|
||||
return Kind is RuntimeInitialCreateTailActionKind.ResidentCellCleanup
|
||||
? payloadCount == 0
|
||||
: payloadCount == 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// One accepted Position packet which arrived before the immutable initial
|
||||
/// CreateObject admission completed. These records remain dormant until a
|
||||
/// host adopts the completed batch; accepting them never replaces or mutates
|
||||
/// the initial 0x11 SetPosition operation.
|
||||
/// One immutable inbound envelope which arrived while retail's synchronous
|
||||
/// CreateObject critical section was virtualized by an asynchronous initial
|
||||
/// SetPosition. Envelopes are never coalesced. A same-incarnation Create is
|
||||
/// one atomic envelope whose ordered tail is expanded only by the executor.
|
||||
/// Position retains the raw PositionPack and is classified only at the FIFO
|
||||
/// head, after every earlier envelope has committed.
|
||||
/// </summary>
|
||||
internal readonly record struct RuntimeInitialCreateResidenceContinuation(
|
||||
ulong Sequence,
|
||||
RuntimePositionEntityKind EntityKind,
|
||||
RuntimeInitialCreateContinuationKind Kind,
|
||||
ushort InstanceSequence,
|
||||
ushort PositionSequence,
|
||||
ushort PreviousTeleportSequence,
|
||||
ushort TeleportSequence,
|
||||
ushort ForcePositionSequence,
|
||||
ushort AcceptedTeleportSequence,
|
||||
ushort AcceptedForcePositionSequence,
|
||||
PositionTimestampDisposition TimestampDisposition,
|
||||
CreateObject.ServerPosition AcceptedWirePosition,
|
||||
Vector3? PositionPackVelocity,
|
||||
Vector3? AcceptedVelocity,
|
||||
Quaternion? ForcePositionRotation,
|
||||
Vector3? CurrentLocalVelocity,
|
||||
bool ProjectionRequiresTeleportHook,
|
||||
uint PlacementFrame,
|
||||
ulong PositionAuthorityVersion)
|
||||
RuntimeAcceptedPositionSource PositionSource,
|
||||
ImmutableArray<RuntimeInitialCreateTailAction> Actions)
|
||||
{
|
||||
internal bool IsValid => Sequence != 0UL
|
||||
&& EntityKind is RuntimePositionEntityKind.LocalPlayer
|
||||
or RuntimePositionEntityKind.Remote
|
||||
or RuntimePositionEntityKind.Projectile
|
||||
&& PositionAuthorityVersion != 0UL
|
||||
&& TimestampDisposition is PositionTimestampDisposition.Apply
|
||||
or PositionTimestampDisposition.ForcePosition;
|
||||
&& !Actions.IsDefaultOrEmpty
|
||||
&& Actions.All(static action => action.IsStructurallyValid)
|
||||
&& HasMatchingInstances()
|
||||
&& HasValidShape();
|
||||
|
||||
private bool HasMatchingInstances()
|
||||
{
|
||||
for (int index = 0; index < Actions.Length; index++)
|
||||
{
|
||||
if (!Actions[index].MatchesInstance(InstanceSequence))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HasValidShape()
|
||||
{
|
||||
if (Kind is not RuntimeInitialCreateContinuationKind.SameIncarnationCreate)
|
||||
{
|
||||
if (Actions.Length != 1)
|
||||
return false;
|
||||
RuntimeInitialCreateTailAction action = Actions[0];
|
||||
RuntimeInitialCreateTailActionKind expected = Kind switch
|
||||
{
|
||||
RuntimeInitialCreateContinuationKind.ObjDesc =>
|
||||
RuntimeInitialCreateTailActionKind.ObjDesc,
|
||||
RuntimeInitialCreateContinuationKind.Parent =>
|
||||
RuntimeInitialCreateTailActionKind.Parent,
|
||||
RuntimeInitialCreateContinuationKind.Pickup =>
|
||||
RuntimeInitialCreateTailActionKind.Pickup,
|
||||
RuntimeInitialCreateContinuationKind.Position =>
|
||||
RuntimeInitialCreateTailActionKind.Position,
|
||||
RuntimeInitialCreateContinuationKind.Movement =>
|
||||
RuntimeInitialCreateTailActionKind.Movement,
|
||||
RuntimeInitialCreateContinuationKind.State =>
|
||||
RuntimeInitialCreateTailActionKind.State,
|
||||
RuntimeInitialCreateContinuationKind.Vector =>
|
||||
RuntimeInitialCreateTailActionKind.Vector,
|
||||
_ => throw new InvalidOperationException(
|
||||
$"Unsupported initial-Create continuation kind {Kind}."),
|
||||
};
|
||||
return action.Kind == expected
|
||||
&& (Kind is RuntimeInitialCreateContinuationKind.Position
|
||||
? PositionSource is RuntimeAcceptedPositionSource.PositionEvent
|
||||
&& action.PositionSource == PositionSource
|
||||
: PositionSource is RuntimeAcceptedPositionSource.Unknown);
|
||||
}
|
||||
|
||||
if (Actions.Length < 2
|
||||
|| Actions[^2].Kind
|
||||
is not RuntimeInitialCreateTailActionKind.WeenieDescription
|
||||
|| Actions[^1].Kind
|
||||
is not RuntimeInitialCreateTailActionKind.ResidentCellCleanup)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasPosition = Actions.Any(
|
||||
static action => action.Kind
|
||||
is RuntimeInitialCreateTailActionKind.Position);
|
||||
if (hasPosition
|
||||
? PositionSource
|
||||
is not RuntimeAcceptedPositionSource.SameIncarnationCreate
|
||||
: PositionSource is not RuntimeAcceptedPositionSource.Unknown)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int previousStage = -1;
|
||||
int positionBranchCount = 0;
|
||||
for (int index = 0; index < Actions.Length; index++)
|
||||
{
|
||||
RuntimeInitialCreateTailAction action = Actions[index];
|
||||
int stage = SameCreateStage(action.Kind);
|
||||
if (stage <= previousStage)
|
||||
return false;
|
||||
if (action.Kind is RuntimeInitialCreateTailActionKind.Position
|
||||
&& action.PositionSource != PositionSource)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (action.Kind is RuntimeInitialCreateTailActionKind.CreateParent
|
||||
or RuntimeInitialCreateTailActionKind.Pickup
|
||||
or RuntimeInitialCreateTailActionKind.Position)
|
||||
{
|
||||
positionBranchCount++;
|
||||
}
|
||||
previousStage = stage;
|
||||
}
|
||||
bool hasPhysicsDescription = Actions.Any(
|
||||
static action => action.Kind
|
||||
is RuntimeInitialCreateTailActionKind
|
||||
.PreTailDescriptionAdaptation);
|
||||
return hasPhysicsDescription
|
||||
? positionBranchCount <= 1
|
||||
: positionBranchCount == 0;
|
||||
}
|
||||
|
||||
private static int SameCreateStage(RuntimeInitialCreateTailActionKind kind) =>
|
||||
kind switch
|
||||
{
|
||||
RuntimeInitialCreateTailActionKind.PreTailDescriptionAdaptation => 0,
|
||||
RuntimeInitialCreateTailActionKind.ObjDesc => 1,
|
||||
RuntimeInitialCreateTailActionKind.CreateParent
|
||||
or RuntimeInitialCreateTailActionKind.Pickup
|
||||
or RuntimeInitialCreateTailActionKind.Position => 2,
|
||||
RuntimeInitialCreateTailActionKind.Movement => 3,
|
||||
RuntimeInitialCreateTailActionKind.State => 4,
|
||||
RuntimeInitialCreateTailActionKind.Vector => 5,
|
||||
RuntimeInitialCreateTailActionKind.WeenieDescription => 6,
|
||||
RuntimeInitialCreateTailActionKind.ResidentCellCleanup => 7,
|
||||
_ => int.MinValue,
|
||||
};
|
||||
}
|
||||
|
||||
internal readonly record struct RuntimeInitialCreateResidenceAdoptionToken(
|
||||
|
|
@ -259,125 +501,37 @@ internal sealed class RuntimeInitialCreateResidenceState
|
|||
return Own(record, route);
|
||||
}
|
||||
|
||||
internal RuntimeInitialCreateResidenceLease EnqueueAcceptedPosition(
|
||||
internal RuntimeInitialCreateResidenceLease EnqueueAccepted(
|
||||
RuntimeEntityRecord record,
|
||||
in RuntimeInitialCreateResidenceLease prior,
|
||||
WorldSession.EntityPositionUpdate update,
|
||||
in WorldSession.EntitySpawn accepted,
|
||||
PositionTimestampDisposition disposition,
|
||||
in AcceptedPhysicsTimestamps timestamps,
|
||||
bool isLocalPlayer,
|
||||
Quaternion? forcePositionRotation,
|
||||
Vector3? currentLocalVelocity,
|
||||
bool projectionRequiresTeleportHook)
|
||||
RuntimeInitialCreateContinuationKind kind,
|
||||
RuntimeAcceptedPositionSource positionSource,
|
||||
ImmutableArray<RuntimeInitialCreateTailAction> actions)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(record);
|
||||
if (!_entities.IsCurrent(record)
|
||||
|| record.Key is not { } key
|
||||
|| update.Guid != record.ServerGuid
|
||||
|| accepted.Guid != record.ServerGuid
|
||||
|| disposition is PositionTimestampDisposition.Rejected)
|
||||
var owned = ImmutableArray.CreateBuilder<
|
||||
RuntimeInitialCreateTailAction>(actions.Length);
|
||||
foreach (RuntimeInitialCreateTailAction action in actions)
|
||||
{
|
||||
return default;
|
||||
owned.Add(RuntimeInitialCreateAdmissionFreezer.Freeze(action));
|
||||
}
|
||||
|
||||
RuntimeInitialCreateResidenceLease current;
|
||||
Entry? active = null;
|
||||
CompletedEntry? completed = null;
|
||||
if (_entries.TryGetValue(key, out active)
|
||||
&& ReferenceEquals(active.Record, record)
|
||||
&& active.Lease.Token == prior.Token
|
||||
&& IsCurrent(active))
|
||||
{
|
||||
current = active.Lease;
|
||||
}
|
||||
else if (_completed.TryGetValue(key, out completed)
|
||||
&& ReferenceEquals(completed.Record, record)
|
||||
&& completed.Lease.Token == prior.Token
|
||||
&& IsCompletedCurrent(completed))
|
||||
{
|
||||
current = completed.Lease;
|
||||
}
|
||||
else
|
||||
{
|
||||
return default;
|
||||
}
|
||||
if (current.Continuations.Length == int.MaxValue
|
||||
|| completed is not null
|
||||
&& completed.Receipt.Adoption.Revision == ulong.MaxValue)
|
||||
return default;
|
||||
|
||||
RuntimePositionEntityKind entityKind = isLocalPlayer
|
||||
? RuntimePositionEntityKind.LocalPlayer
|
||||
: (record.FinalPhysicsState & PhysicsStateFlags.Missile) != 0
|
||||
? RuntimePositionEntityKind.Projectile
|
||||
: RuntimePositionEntityKind.Remote;
|
||||
CreateObject.ServerPosition acceptedPosition =
|
||||
accepted.Position ?? update.Position;
|
||||
ushort previousTeleport = current.Continuations.IsEmpty
|
||||
? current.Route.Authority.AcceptedTeleportSequence
|
||||
: current.Continuations[^1].AcceptedTeleportSequence;
|
||||
ulong sequence = (ulong)current.Continuations.Length + 1UL;
|
||||
var continuation = new RuntimeInitialCreateResidenceContinuation(
|
||||
sequence,
|
||||
entityKind,
|
||||
update.InstanceSequence,
|
||||
update.PositionSequence,
|
||||
previousTeleport,
|
||||
update.TeleportSequence,
|
||||
update.ForcePositionSequence,
|
||||
timestamps.Teleport,
|
||||
timestamps.ForcePosition,
|
||||
disposition,
|
||||
acceptedPosition,
|
||||
update.Velocity,
|
||||
accepted.Physics?.Velocity,
|
||||
forcePositionRotation,
|
||||
currentLocalVelocity,
|
||||
projectionRequiresTeleportHook,
|
||||
accepted.PlacementId ?? 0u,
|
||||
record.PositionAuthorityVersion);
|
||||
if (!continuation.IsValid)
|
||||
return default;
|
||||
|
||||
RuntimeInitialCreateResidenceLease revised = current with
|
||||
{
|
||||
Continuations = current.Continuations.Add(continuation),
|
||||
};
|
||||
if (active is not null)
|
||||
{
|
||||
active.Lease = revised;
|
||||
}
|
||||
else
|
||||
{
|
||||
completed!.Lease = revised;
|
||||
RuntimeInitialCreateResidenceAdoptionToken revisedAdoption =
|
||||
completed.Receipt.Adoption with
|
||||
{
|
||||
Revision = completed.Receipt.Adoption.Revision + 1UL,
|
||||
};
|
||||
completed.Receipt = completed.Receipt with
|
||||
{
|
||||
Adoption = revisedAdoption,
|
||||
Continuations = revised.Continuations,
|
||||
};
|
||||
}
|
||||
return revised;
|
||||
return Enqueue(
|
||||
record,
|
||||
prior,
|
||||
new RuntimeInitialCreateResidenceContinuation(
|
||||
NextSequence(prior),
|
||||
kind,
|
||||
record.Incarnation,
|
||||
positionSource,
|
||||
owned.MoveToImmutable()));
|
||||
}
|
||||
|
||||
internal bool CanEnqueueAcceptedPosition(
|
||||
internal bool CanEnqueue(
|
||||
RuntimeEntityRecord record,
|
||||
in RuntimeInitialCreateResidenceLease prior,
|
||||
in WorldSession.EntityPositionUpdate update)
|
||||
in RuntimeInitialCreateResidenceLease prior)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(record);
|
||||
if (record.Key is not { } key
|
||||
|| update.Guid != record.ServerGuid
|
||||
|| !RuntimeAuthoritativePositionRouteClassifier
|
||||
.IsValidCreateWirePosition(update.Position))
|
||||
{
|
||||
if (record.Key is not { } key)
|
||||
return false;
|
||||
}
|
||||
if (_entries.TryGetValue(key, out Entry? entry))
|
||||
{
|
||||
return ReferenceEquals(entry.Record, record)
|
||||
|
|
@ -393,6 +547,61 @@ internal sealed class RuntimeInitialCreateResidenceState
|
|||
&& completed.Receipt.Adoption.Revision < ulong.MaxValue;
|
||||
}
|
||||
|
||||
private RuntimeInitialCreateResidenceLease Enqueue(
|
||||
RuntimeEntityRecord record,
|
||||
in RuntimeInitialCreateResidenceLease prior,
|
||||
in RuntimeInitialCreateResidenceContinuation continuation)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(record);
|
||||
if (!continuation.IsValid
|
||||
|| continuation.InstanceSequence != record.Incarnation
|
||||
|| !CanEnqueue(record, prior))
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
RuntimeEntityKey key = record.Key!.Value;
|
||||
Entry? active = null;
|
||||
CompletedEntry? completed = null;
|
||||
RuntimeInitialCreateResidenceLease current;
|
||||
if (_entries.TryGetValue(key, out active))
|
||||
current = active.Lease;
|
||||
else if (_completed.TryGetValue(key, out completed))
|
||||
current = completed.Lease;
|
||||
else
|
||||
return default;
|
||||
|
||||
if (continuation.Sequence != NextSequence(current))
|
||||
return default;
|
||||
RuntimeInitialCreateResidenceLease revised = current with
|
||||
{
|
||||
Continuations = current.Continuations.Add(continuation),
|
||||
};
|
||||
if (active is not null)
|
||||
{
|
||||
active.Lease = revised;
|
||||
}
|
||||
else
|
||||
{
|
||||
completed!.Lease = revised;
|
||||
RuntimeInitialCreateResidenceAdoptionToken adoption =
|
||||
completed.Receipt.Adoption with
|
||||
{
|
||||
Revision = completed.Receipt.Adoption.Revision + 1UL,
|
||||
};
|
||||
completed.Receipt = completed.Receipt with
|
||||
{
|
||||
Adoption = adoption,
|
||||
Continuations = revised.Continuations,
|
||||
};
|
||||
}
|
||||
return revised;
|
||||
}
|
||||
|
||||
private static ulong NextSequence(
|
||||
in RuntimeInitialCreateResidenceLease lease) =>
|
||||
(ulong)lease.Continuations.Length + 1UL;
|
||||
|
||||
internal bool TryGetTransaction(
|
||||
RuntimeEntityRecord record,
|
||||
out RuntimeInitialCreateResidenceLease lease)
|
||||
|
|
@ -457,6 +666,7 @@ internal sealed class RuntimeInitialCreateResidenceState
|
|||
token,
|
||||
route,
|
||||
placement,
|
||||
RuntimeInitialCreateAdmissionFreezer.Freeze(record.Snapshot),
|
||||
ImmutableArray<RuntimeInitialCreateResidenceContinuation>.Empty);
|
||||
_entries.Add(key, new Entry
|
||||
{
|
||||
|
|
@ -600,6 +810,12 @@ internal sealed class RuntimeInitialCreateResidenceState
|
|||
Retire(current);
|
||||
return false;
|
||||
}
|
||||
// Admission-only checkpoint: a completed initial placement remains
|
||||
// owned until the next slice's continuation executor has drained the
|
||||
// exact FIFO revision. Letting a host acknowledge here would silently
|
||||
// discard accepted packets.
|
||||
if (!current.Lease.Continuations.IsEmpty)
|
||||
return false;
|
||||
if (current.Lease.Route.PerformsSetPosition
|
||||
&& !_setPosition.ConsumeAcknowledgedPlacement(
|
||||
current.Lease.Placement,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue