You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: spec/rcv-services.md
+6Lines changed: 6 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -478,6 +478,8 @@ update (s, idsHash) =
478
478
|**R-SVC-05**| Fold blocking | Low |`foldRcvServiceMessages` iterates all service queues sequentially, reading queue records and first messages. For services with many queues, this could take significant time. It runs in a forked thread, so it doesn't block the client's command processing, but the ALLS marker is delayed. No progress signal between SOKS and ALLS -- client doesn't know how many messages to expect. |
479
479
|**R-SVC-06**| XOR hash collision | Very Low | IdsHash uses XOR of MD5 hashes. XOR is commutative and associative, so different queue sets with the same XOR-combined hash would not be detected. Given 16-byte hashes, collision probability is negligible for realistic queue counts, but the hash provides no ordering information. |
480
480
|**R-SVC-07**| Count underflow in subtractServiceSubs | Very Low | If `n <= n'`, the function returns `(0, mempty)` -- a full reset. This is a defensive fallback but could mask accounting errors. |
481
+
|**R-SVC-08**| Big agent service handling diverged from small agent | Medium | Small agent (Client/Agent.hs, NTF-proven) has cleaner service unavailable handling: `notifyUnavailable` clears pending service sub and sends `CAServiceUnavailable` event, triggering queue-by-queue resubscription. Big agent (Agent/Client.hs) lacks equivalent path - errors throw without clearing pending state. TransportSessionMode adds complexity (per-entity vs per-user sessions). Service role validation differs (small agent checks `partyServiceRole`, big agent doesn't). These differences may cause subtle bugs when releasing rcv-services. |
482
+
|**R-SVC-09**| Server deferred delivery broken for service queues | Critical | In `tryDeliverMessage` (Server.hs), when a message arrives and the subscribed client's `sndQ` is full, the sync path correctly checks `rcvServiceId qr` to find the service subscriber (lines 1996-1998). But the spawned `deliverThread` (line 2043) hardcodes `getSubscribedClient rId (queueSubscribers subscribers)` - it looks in `queueSubscribers` instead of `serviceSubscribers`. For service-subscribed queues, `deliverThread` will never find the client. The message remains marked `SubPending` but is never delivered. Only reconnection or explicit re-subscription will deliver it. Impact: under load when sndQ fills, service clients silently lose message delivery until reconnection. |
481
483
482
484
### Considered and dismissed
483
485
@@ -705,3 +707,7 @@ Triggers use `xor_combine` (Postgres equivalent of XOR hash combine) and fire on
705
707
|**TG-SVC-10**| Medium | No agent-level test for concurrent reconnection — service resubscription racing with individual queue resubscription |
706
708
|**TG-SVC-11**| Medium | No test for `SERVICE_END` agent event handling — what does the agent do after receiving ENDS? |
707
709
|**TG-SVC-12**| Low | No test for SQLite trigger correctness — verifying `service_queue_count`/`service_queue_ids_hash` match expected values after insert/delete/update cycles |
710
+
|**TG-SVC-13**| High | Big agent lacks `CAServiceUnavailable` equivalent — no clean path to resubscribe all queues individually when service becomes unavailable. Small agent has `notifyUnavailable` which triggers queue-by-queue resubscription; big agent just throws error |
711
+
|**TG-SVC-14**| Medium |`pendingServiceSub` not cleared on service errors — small agent clears pending in `notifyUnavailable`; big agent may retain stale pending service subs after `clientServiceError` or `SSErrorServiceId`|
712
+
|**TG-SVC-15**| High | Missing `rcvServiceAssoc` cleanup on service unavailable — TODO at Agent/Client.hs:1742 notes this is incomplete. When service ID changes or becomes unavailable, queue associations should be cleared in database |
713
+
|**TG-SVC-16**| Critical |**Server bug**: `deliverThread` uses wrong subscriber lookup for service queues — At Server.hs:2043, deferred delivery (when sndQ is full) always uses `queueSubscribers`, but service clients are in `serviceSubscribers`. The sync path (lines 1996-1998) correctly checks `rcvServiceId qr`. Messages sent when sndQ is full will never be delivered to service subscribers until reconnection/resubscription. |
0 commit comments