CultNet client: a straggler's subscription is judged under the lock Unsubscribe evicts under; tests pin the shared budget, ghost ids, a real database server, and Reconcile after a policy change

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Libby 2026-11-11 04:06:45 +00:00
commit dbe3171d1f
2 changed files with 174 additions and 6 deletions

View file

@ -245,14 +245,13 @@ namespace GameCult.Networking
return Apply(deliveryMode, new[] { message });
// The commit's other changes follow on this connection; the replica applies them as one commit.
// A straggler of a subscription that was ended, or never made, is not buffered.
if (!_deliveryModes.ContainsKey(message.SubscriptionId))
return Task.CompletedTask;
var held = (message.SubscriptionId, message.CommitId);
PendingCommit? pending;
lock (_commits)
{
if (Fault != null)
// A straggler of a subscription that was ended, or never made, is not buffered. Judged under the lock that
// Unsubscribe evicts under: a check before it could pass, lose the race to the eviction, and then buffer.
if (Fault != null || !_deliveryModes.ContainsKey(message.SubscriptionId))
return Task.CompletedTask;
var count = message.CommitCount!.Value;
var refusal = !_commits.TryGetValue(held, out pending)