Repository navigation
tests: the driver/postgres Query_1col_1row allocation guard no longer counts its fake backend's allocations or depends on how its reply is segmented (v1.6.0, Refs #890 #1104) - #1162
Merged
Conversation
|
Caution Review failedThe pull request is closed.
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
Flakes lane.
driver/postgresTestAllocBudgets/Query_1col_1rowfailedallocs/op=15 (budget 14)in the step "celeris#890 allocation guards and alloc-count tests, without -race" on #1154 (run 40732286713, job 122971490732) and on #1150 (head 323fe30). Tests only, no driver change. Refs #890, Refs #1104, Refs #1154, Refs #1150What the 15 is
AllocsPerOpfloors (an integer division), so a 15 against 14 means almost every query of the final benchmark round allocated one more, not one stray allocation. The extra allocation is thecolsChof the sync fast path's fall-through (simpleQuery, "Partial or EAGAIN"): when the poll on the caller's goroutine reads only part of the reply it falls through to the async wait and allocates the channel there. That is the same +1 that #1144 measured for a platform without a sync poll (syncLoop == nil: 15).Why the poll can read only part: the guard's fake backend wrote its reply as FOUR
writes (RowDescription, DataRow, CommandComplete, ReadyForQuery), so whether the poll found all four depended on the backend's writes against the poll's phases (one read, 16 x poll(0)+Gosched, poll(1ms)). A postgres backend flushes at ReadyForQuery, one segment.A second finding: the 14 was not the driver's cost.
testing.Benchmarkcounts the whole process, and about 10 of the 14 were the fake backend's (writeMsgx4,buildRowDescriptionx2,readMsg; heap profile at rate 1, in the evidence). With a prebuilt reply, one write and a reused read buffer the driver costs 4 allocs/op on the sync path (the "aspirational 4" this row held before #890 item 91 set it to 14) and 5 without the sync poll or with a reply in pieces.Reproduction (what is and is not shown)
golang:1.27.3,--cpus 2.-count=60(one process), 100 fresh processes with the CI selection, GOMAXPROCS 1, 2, 4, 8 x--cpus0.3, 0.5, 1, 2 (40 runs each). So the claim that CI's 15 was a reply read in pieces is an inference from the mechanism (the arithmetic of the floor, the allocation site, the fake's four writes); I did not observe a split on a failing run. If the cause on that runner is another persistent +1, the new guard (4) fails there too and says so.Commits
tests: ... counts 15, not 14, when the backend's writes of a reply are apart(red on main): a seam (fakePGWriteGap) andTestQuery1col1rowGuardDoesNotDependOnTheReplyArrivingInPieces1104: gap 0 passes (14), gap 300 us fails (15 against 14), 20 of 20.tests: the Query_1col_1row guard's fake backend answers in one segment from a prebuilt reply ...: the backend builds the reply once and writes it once; the budget is the driver's 4 (5 without the sync poll); a second rowQuery_1col_1row_reply_in_pieces(budget 5) prices the fall-through (2 ms between the writes, so a whole read needs a 6 ms stall). Both are rows ofTestAllocBudgets, so the ci.yml entry list and the count of 15 do not change (the discovery check in that step names top-level tests of!racefiles). The commit-1 test is replaced by these rows.Numbers
--cpus 2, strict,-count=30-count=3)colsChallocated on the sync path tooThe mutant matters: the old 14 had ten allocations of slack for the driver (the backend's), so a driver regression of +1 was invisible. With the driver's own 4 it is caught.
go vetlinux, darwin, windows;golangci-lint0 new findings (rowch_failall_887_test.go:311errcheck is on main). The windows Portable fallback job is unmeasured here: its path is the no-sync-poll one, 5, as on darwin.Release note
None (tests only).