Repository navigation
fix(cds-caching): atomic UPSERT in KeyvCDS.set to stop PK-collision error noise (#3102) - #3107
Merged
Merged
Conversation
…rror noise (#3102) KeyvCDS.set did a read-then-create/update (TOCTOU). Under multi-instance CF two instances both read 'no row', both INSERT the same CacheStore key, and the second INSERT violates the PK unique index — logged at error level (the PROD kg:rl:* rate-limiter noise) with the losing write dropped. Replace that branch with an atomic single-key UPSERT (last-write-wins) via a committed patch-package patch against cds-caching@2.1.0. Add a regression test driving the real KeyvCDS against an in-memory CAP fixture, modelling the TOCTOU window deterministically.
…3102) Add patch-package devDep + a postinstall hook so the cds-caching@2.1.0 UPSERT patch re-applies on every npm ci / npm install. prepare (git hooks) is left intact; both hooks fire on install.
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.
Fixes #3102.
Problem
In PROD (
tutorials-srv),cds-cachinglogs recurring error-level lines when two HA instances concurrently write the same cache key — seen for the KG rate-limiter (kg:rl:api:auth:...,kg:rl:homepage:anon:<ip>):Root cause: the vendored plugin's
KeyvCDS.set()does a read-then-create/update (TOCTOU). Under multi-instance CF, two instances both read "no row", both take the INSERT branch, and the second INSERT collides on theCacheStoreprimary-key unique index. The plugin logs the collision aterrorand swallows it — so it's functionally fail-open (the rate limiter already over-allows under races, which is acceptable), but it spams prod error monitoring and drops the losing write.Fix
A committed patch-package patch (
patches/cds-caching+2.1.0.patch) replaces that branch with a single atomic UPSERT:CacheStorehas a single-column PK (ID), so this compiles to HANAUPSERT ... WITH PRIMARY KEY/ SQLiteINSERT OR REPLACE— last-write-wins, no read-then-write race, one fewer round-trip. The patch re-applies on everynpm ci/npm installvia a newpostinstallhook (prepare/git-hooks left intact).Scope is deliberately
set()only.get/has/deletealso read-then-write, but they only ever delete (idempotent under concurrency) — they don't collide on an INSERT, so they produce no error noise.Tests
srv/lib/__tests__/keyv-cds-upsert.test.jsdrives the realKeyvCDSagainst a minimal in-memory CAP fixture (srv/lib/__tests__/__fixtures__/keyv-cds-app/). The decisive test models the multi-instance TOCTOU window deterministically (stubsdb.readto miss while the row physically exists); it fails on the unpatched plugin (1set error+ lost write) and passes on the patched plugin (0 errors, value persisted). Verified both directions.cds compile srvis clean; the fixture'sCacheStoredoes not leak into the main CAP model (fixturepackage.jsonboundary +__tests__convention).Upstream
The same read-then-insert is still on
cds-cachingmain. Upstreamed as mikezaschka/cds-caching#44 (issue) + mikezaschka/cds-caching#45 (PR). Drop condition: delete the patch once a published release carries the fix and we adopt it. Docs:docs/developers/reference/cds-caching-store.md-> "KeyvCDS.set UPSERT patch (#3102)".Reviewed
Whole-branch review (fresh agent): APPROVE, no Critical/Important findings; patch apply, hunk math,
cds.ql.UPSERTresolution, and the RED->GREEN regression all independently verified.