Refuse variants after the selection is applied, and never tell a subscriber about the removal of one it was only refused
The selection paths (SelectPage, SelectAll) refused every stored variant before the selection ran, so once any variant existed a hop-bearing subscription threw out of its change handler and went silent. They now refuse only a variant the selection selects; the subscription server delivers that as a typed error and keeps its projection. The database server no longer sends removed for a key the subscriber only ever received as an error. A flatten racing the delivery check is recorded in a comment. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
354f9743e6
commit
b572823d0d
4 changed files with 240 additions and 24 deletions
|
|
@ -204,6 +204,13 @@ namespace GameCult.Networking
|
|||
peer.SendCultNet(CultNetErrorMessage.ForReferenceOutsideTarget(ex));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch (NotSupportedException refusal)
|
||||
{
|
||||
// Q6: a snapshot that selects a variant is refused to this subscriber as a typed error.
|
||||
Withdraw(key, sendRemovals: false, forgetRequest: true);
|
||||
peer.SendCultNet(new CultNetErrorMessage { Error = refusal.Message });
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Withdraw(key, sendRemovals: false, forgetRequest: true);
|
||||
|
|
@ -342,9 +349,20 @@ namespace GameCult.Networking
|
|||
if (!_projections.TryGetValue(key, out var projection)) return;
|
||||
var legacyRequest = request.ToLegacyShape(key.Id);
|
||||
var authorized = _authorizeRequest?.Invoke(legacyRequest, key.Peer) != false;
|
||||
var next = authorized
|
||||
? CreateProjectedSnapshot(request, key.Peer)
|
||||
: ProjectedSnapshot.Empty;
|
||||
ProjectedSnapshot next;
|
||||
try
|
||||
{
|
||||
next = authorized
|
||||
? CreateProjectedSnapshot(request, key.Peer)
|
||||
: ProjectedSnapshot.Empty;
|
||||
}
|
||||
catch (NotSupportedException refusal)
|
||||
{
|
||||
// Q6: the selection selects a variant, which CultNet cannot carry. This subscriber is told, by key, and keeps what
|
||||
// it was delivered; a change never throws out of the change handler.
|
||||
key.Peer.SendCultNet(new CultNetErrorMessage { Error = refusal.Message });
|
||||
return;
|
||||
}
|
||||
|
||||
// With _projectRecord gone (docs/cultnet-selection-cut.md, S2-2), a projection's dictionary
|
||||
// key is always the record's own RecordKey/SchemaId, so the two can never disagree here;
|
||||
|
|
|
|||
Loading…
Reference in a new issue