Skip to content

[slopfix] refactor(universaldb,ups): single/multi-node udb over nats, remove ups postgres driver - #5354

Open
MasterPtato wants to merge 1 commit into
stack/slopfix-perf-universaldb-fold-postgres-drain_batch-into-claim-nextval-and-single-apply-cte-pnzolyqxfrom
stack/slopfix-refactor-universaldb-ups-single-multi-node-udb-over-nats-remove-ups-postgres-driver-vuorlwlu
Open

[slopfix] refactor(universaldb,ups): single/multi-node udb over nats, remove ups postgres driver#5354
MasterPtato wants to merge 1 commit into
stack/slopfix-perf-universaldb-fold-postgres-drain_batch-into-claim-nextval-and-single-apply-cte-pnzolyqxfrom
stack/slopfix-refactor-universaldb-ups-single-multi-node-udb-over-nats-remove-ups-postgres-driver-vuorlwlu

Conversation

@MasterPtato

@MasterPtato MasterPtato commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@MasterPtato

MasterPtato commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

Stack for rivet-dev/rivet

Get stack: forklift get 5354
Push local edits: forklift submit
Merge when ready: forklift merge 5354

change vuorlwlu

@claude

claude Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review: single/multi-node UDB over NATS, remove UPS postgres driver

This is a large, well-documented rearchitecture of the UniversalDB Postgres driver (in-process leader/follower over NATS request/reply, dedup-based exactly-once commit application) plus removal of the standalone Postgres universalpubsub driver. Overall the design is solid — the failover dedup key (client_node_id + client_seq via udb_applied), the epoch-fenced apply CTE, and the batched drain loop are carefully reasoned through (the in-code comments explaining the cold-window floor and dedup pipelining are excellent). A few things worth a look before merging:

Correctness / design

  • max_retries cut from 100 → 10 in both engine/packages/universaldb/src/driver/postgres/database.rs and driver/rocksdb/database.rs. This is the transaction-level retry-on-conflict budget, a different layer from the new 8-attempt NATS resend loop in commit.rs. Reducing it 10x changes write availability under sustained contention (a txn that previously succeeded after, say, 40 conflict retries now gives up after 10). No comment explains the rationale — worth confirming this is intentional and was validated under a contended workload, since it applies to rocksdb too, which isn't touched by anything else in this PR.

  • wait_for_leader in commit.rs busy-polls shared.current_lease() every 50ms (LEADER_POLL_INTERVAL) up to a 5s deadline. PostgresShared already carries a tokio::sync::watch::Sender<Option<LeaseInfo>>/Receiver for the lease (see shared.rs), so this could await lease_rx.changed() instead of sleep-polling, consistent with the repo's guidance to pair shared state with a Notify/watch rather than loop { check; sleep }. Since this function was touched in this PR anyway (constant renamed/retuned), might be worth fixing while it's in scope.

  • v1.bare (universaldb-commit) CommitRequest was modified in place (added clientNodeId/clientSeq) rather than introducing a v2 schema. I checked and this schema doesn't exist on main yet (it's part of this same unmerged stack), so this isn't an active violation of the "don't modify a published vbare schema" rule today — but the struct's own doc comment says it's "versioned so rolling deploys can skew follower vs leader code," which this change undercuts within the stack. Worth double-checking whether any earlier commit in the stack has already shipped to a staging/canary environment where mixed old/new binaries could hit this.

Breaking change to flag explicitly

  • PubSub::PostgresNotify config variant is removed outright (engine/packages/config/src/config/pubsub.rs), and Root::validate_and_set_defaults no longer synthesizes it as a default. Given #[serde(deny_unknown_fields)] on the PubSub enum, any existing self-hosted deployment with pubsub: { postgres_notify: ... } in its config will now fail to parse entirely (hard startup failure) after upgrading, with no deprecation warning or migration path — it just becomes an unknown-variant error. That's consistent with this repo's general "no compat shims" stance, but given this used to be a documented alternative to NATS for self-hosters without a NATS deployment, it's worth a callout in the PR description / release notes so it isn't a surprise.

  • Related: a multi-node Postgres UDB deployment that was running today without NATS pub/sub configured (the old NOTIFY/table-based commit-queue transport supported this) will fail to boot as of this change unless the operator adds a nats config — PostgresDatabaseDriver::new_with_config now bail!s from acquire_single_node_gate if a second node can't acquire the lease and no NATS config is present ("if you intend to run a multi-node setup you must configure NATS"). This looks intentional and is reflected correctly in the self-host templates, but again worth flagging explicitly as an operational/upgrade note since it's a hard requirement change, not just a new option.

Nits

  • run_commit_subscriber in nats.rs silently drops requests that fail to decode or are missing a reply subject (just logs and continues) — fine given the follower's own retry/timeout covers it, no action needed, just noting it's intentionally fire-and-forget.

Test coverage

Good — tests/failover.rs was updated to spin up NATS and exercise both leader failover and graceful handoff in multi-node mode, and the pubsub benches/integration/reconnect tests for the removed Postgres driver were cleanly deleted rather than left dangling. I didn't spot any leftover references to the deleted postgres pubsub driver or udb_commit_requests table elsewhere in the tree.

Nice cleanup overall — the diff removes a lot more than it adds (~2500 deletions vs ~1300 additions) while consolidating two previously-separate Postgres NOTIFY-based subsystems onto one NATS transport.

@MasterPtato
MasterPtato force-pushed the stack/slopfix-refactor-universaldb-ups-single-multi-node-udb-over-nats-remove-ups-postgres-driver-vuorlwlu branch from fc555e6 to c2f534e Compare August 7, 2026 01:27
@MasterPtato
MasterPtato changed the base branch from main to stack/slopfix-perf-universaldb-fold-postgres-drain_batch-into-claim-nextval-and-single-apply-cte-pnzolyqx August 7, 2026 01:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant