DialogQueue.enqueue is not robust to a synchronous settle (latent FIFO/queue corruption) #29
Labels
No labels
bug
enhancement
pr-split
question
security
transaction-matcher
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
momsse/octant#29
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
DialogQueue.enqueue(apps/backoffice/src/lib/client/common/components/dialog-queue.ts) has a latent ordering bug: if amakeRequestcallback ever invokessettlesynchronously (before returning theRequest), the queue state is corrupted. It is not reachable with today's callers, so we are deliberately deferring the fix — this issue records the context and what a proper fix needs.The defect
If
settlefires synchronously insidemakeRequest,activateNextRequest()runs beforethis.activeRequestis assigned: it shifts from an emptypendingRequests, setsactiveRequest = null, and notifiesnull. Control then returns to thethis.activeRequest === nullguard, which istrue, so the already-settled request is installed as the active dialog and shown — permanently, sincerequestHasSettledblocks its resolve callback from ever firing again.Why we are not fixing it now
DialogsProvider(dialogs.tsx), always builds and returns theRequestobject synchronously and never callssettlefrom insidemakeRequest(settle is wired to user interaction / dialog dismissal). So the corrupting path cannot be hit by current code.resolve(result)beforeactivateNextRequest(). That regresses a real, supported scenario: a.then(() => dialogs.confirm(…))chain. Resolving first runs the chainedenqueue(microtask) before the queue advances, so the chained dialog is appended topendingRequestsand then a different pending request is promoted — breaking the FIFO ordering that currently holds. So this is not a one-line reorder; it needs a deliberate redesign + tests.What a proper fix needs
enqueuerobust to a synchronoussettle: decide activation based on whether the settling request is the active one, not on a guard that runs aftermakeRequestreturns. Options: assignactiveRequest/enqueue before invokingmakeRequest, or have the settle callback no-op itsactivateNextRequest()when the request was never activated..then(() => dialogs.confirm())) — the new active dialog must be promoted before the resolve continuation enqueues the next one (current behaviour), or chained requests must be ordered deterministically by design.dialog-queue.test.tscovering: (a) synchronous settle insidemakeRequest, and (b) a chainedconfirm-in-.thenpreserving order — both currently missing.Context
split/13-backoffice). Latent only; no user-visible impact with the currentDialogsProvider.