Replication migration deploy 2: leaders send TRANSACTION, followers send FOLLOWER_STATUS - #2725
Open
tylerkaraszewski wants to merge 4 commits into
Open
Replication migration deploy 2: leaders send TRANSACTION, followers send FOLLOWER_STATUS#2725tylerkaraszewski wants to merge 4 commits into
tylerkaraszewski wants to merge 4 commits into
Conversation
…CTION Every transaction a leader broadcasts has already committed locally, so there is no reason to hold the follower's copy open across two messages. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Nothing acts on an approval any more, so the only thing a follower owes leader is a periodic commit-count report. Every message already carries CommitCount, so FOLLOWER_STATUS needs no body of its own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
No leader in the cluster can send this any more: the previous release stopped sending it, and this release only ships once every node is running that one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Details
Deploy 2 of 3 in the replication protocol migration. Remove QUORUM commits was deploy 1, and it's out everywhere, which is the only precondition for this one.
Deploy 1 added receivers for the new messages without sending any of them. This deploy starts sending them:
TRANSACTIONinstead of theBEGIN_TRANSACTION+COMMIT_TRANSACTIONpair. Every transaction leader broadcasts has already committed locally, so there was never a reason to hold the follower's copy open across two messages.FOLLOWER_STATUSinstead ofAPPROVE_TRANSACTION, everyMIN_APPROVE_FREQUENCYth commit. Nothing acts on an approval any more, so the only thing a follower owes leader is a rough idea of how far along it is, and every message already carries that in itsCommitCountheader. That collapsed the whole approve/deny block down to four lines, since there's no longer an ASYNC-vs-not distinction to make on the response path.ROLLBACK_TRANSACTIONreceiver.That last one is why this couldn't be merged into deploy 1. A leader running pre-deploy-1 code still sends
ROLLBACK_TRANSACTIONon a commit conflict, and a follower with no handler for it falls through to_replicate's unrecognized-command warning and keeps its prepared transaction open. The nextBEGIN_TRANSACTIONthen throwsalready in a transactionout of a thread with notry/catch, which meansset_terminateand a dead process.BEGIN_TRANSACTIONandCOMMIT_TRANSACTIONreceivers both stay, because during this rolling deploy an un-upgraded leader is still sending them. They go away in deploy 3, along with theASYNC_prefix, theAPPROVE_TRANSACTION/DENY_TRANSACTIONpair, and the four rollback paths that only exist because a follower could hold a prepared transaction between two messages.Worth noting for whoever reviews: nothing in the code enforces the ordering here. There's no replication protocol version on the wire to gate on —
LOGIN["Version"]is an opaque build string that plugin versions feed into and-versionOverridereplaces outright, so it can't be used to decide what a peer can receive. The method line is the discriminator, which is whyTRANSACTIONis a new name rather than a header onBEGIN_TRANSACTION.Fixed Issues
For https://github.com/Expensify/Expensify/issues/669612
Tests
ClusterUpgradeTestis the interesting one — it's the only test that runs two different binaries against each other, and it picks the most recent release tag as the old side. That tag is2026-08-14-373619, which contains deploy 1, so this run actually exercised the deploy-1-leader / deploy-2-follower combination that this PR depends on:proxyTestfails on my VM because squid isn't running, not because of anything here.It still only covers the one upgrade order it performs, so treat it as a floor rather than a proof.
Internal Testing Reminder: when changing bedrock, please compile auth against your new changes