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
{{ message }}
Repository navigation
A durable MQTT session can save a position above a local transaction that has not committed yet, and skip it on resume #3112
A durable MQTT session can still save a position above a local transaction that has taken its log key but not yet committed. Once that transaction commits, its message is delivered below the saved position, and a reconnect never replays it. #3103 (#3101) bounds a saved position only by deliveries the session has already seen, so it does not reach this window. Kris raised this in review of #3103, with the idea below.
Sequence (reproduced on the merged #3103 code, 15fdc80d5, with the heldTransaction helper in unitTests/server/durableSessionResume.test.js):
Transaction L takes its key (call it 50) with a write and stays open.
Another transaction commits with key 100, is delivered, and is acknowledged. Nothing is unacknowledged or queued, so the checkpoint saves progress(), which is 100.
L commits and is delivered. Its bound, just below 50, is below the saved position, and advancePositions() never lowers a generation-bound position.
The client disconnects before acknowledging L. The resumed session replays only keys after 100, so L is silently skipped.
In the run, the saved position stayed at the higher key across the acknowledgement and the disconnect, and the resumed session received only a later write. The same window covers a late transaction already queued behind the message being sent, which the session cannot see either (the open finding noted on #3103).
Idea: bound the saved position by the certified origin-closed floor from #3085. getOriginClosedFloor(rootStore) (resources/originClosedFloor.ts:368) returns a floor below which no local transaction can still append, so a position at or below it cannot be passed by a later local commit. This is #2928's second candidate fix ("cap cursors at the oldest open local write transaction"), and #3085 now provides the write-path coverage that fix needed.
Open design questions:
Where to apply it: in DurableSubscriptionsSession.nextPosition (MQTT only), or in the subscription's progress() (resources/transactionBroadcast.ts / resources/Table.ts), so that every reportProgress consumer gets it.
Lag: the floor is certified every 5 s (ORIGIN_FLOOR_TICK_MS), so saved positions would trail live delivery by up to that much, and a reconnect would redeliver up to ~5 s of acknowledged messages. At-least-once delivery allows that, but it is a visible change.
No floor:getOriginClosedFloor returns undefined on LMDB and before the first certification. Should the session keep today's behavior there, or hold its position?
A durable MQTT session can still save a position above a local transaction that has taken its log key but not yet committed. Once that transaction commits, its message is delivered below the saved position, and a reconnect never replays it. #3103 (#3101) bounds a saved position only by deliveries the session has already seen, so it does not reach this window. Kris raised this in review of #3103, with the idea below.
Sequence (reproduced on the merged #3103 code,
15fdc80d5, with theheldTransactionhelper inunitTests/server/durableSessionResume.test.js):progress(), which is 100.advancePositions()never lowers a generation-bound position.In the run, the saved position stayed at the higher key across the acknowledgement and the disconnect, and the resumed session received only a later write. The same window covers a late transaction already queued behind the message being sent, which the session cannot see either (the open finding noted on #3103).
Idea: bound the saved position by the certified origin-closed floor from #3085.
getOriginClosedFloor(rootStore)(resources/originClosedFloor.ts:368) returns a floor below which no local transaction can still append, so a position at or below it cannot be passed by a later local commit. This is #2928's second candidate fix ("cap cursors at the oldest open local write transaction"), and #3085 now provides the write-path coverage that fix needed.Open design questions:
DurableSubscriptionsSession.nextPosition(MQTT only), or in the subscription'sprogress()(resources/transactionBroadcast.ts/resources/Table.ts), so that everyreportProgressconsumer gets it.ORIGIN_FLOOR_TICK_MS), so saved positions would trail live delivery by up to that much, and a reconnect would redeliver up to ~5 s of acknowledged messages. At-least-once delivery allows that, but it is a visible change.getOriginClosedFloorreturnsundefinedon LMDB and before the first certification. Should the session keep today's behavior there, or hold its position?Test: the sequence above, as a unit test beside the #3101 tests, should fail before the fix and pass after it.