Skip to content

Fix cache invalidation bug when loading a new build#9954

Merged
LocalIdentity merged 2 commits into
PathOfBuildingCommunity:devfrom
Paliak:issue-9947
Jul 20, 2026
Merged

Fix cache invalidation bug when loading a new build#9954
LocalIdentity merged 2 commits into
PathOfBuildingCommunity:devfrom
Paliak:issue-9947

Conversation

@Paliak

@Paliak Paliak commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Fixes #9947

Description of the problem being solved:

See issue

Steps taken to verify a working solution:

  • Run script provided in issue with the extra wipe commented out and adapted to be ran in the tests container:
repro.lua
-- contamination_repro.lua
-- Repro for: stale GlobalCache trigger data survives loading a new build
-- when calcsTab:BuildOutput() is invoked directly (PoB v2.65.0).
-- Run from a stock PathOfBuilding checkout's src/ directory:
--     luajit contamination_repro.lua buildA.xml buildB.xml
-- Expected output: build A's reload (step 3) wrongly reports build B's
-- TotalDPS/SkillTriggerRate; after wipeGlobalCache() they are restored.

-- capture our args BEFORE booting: PoB itself consumes arg[1] as an
-- optional import URL (Modules/Main.lua), so it must not see our paths
local pathA, pathB = assert(arg[1], "arg1: buildA.xml"), assert(arg[2], "arg2: buildB.xml")
arg[1], arg[2] = nil, nil

package.path = package.path .. ";../runtime/lua/?.lua;../runtime/lua/?/init.lua"
dofile("HeadlessWrapper.lua")

local function readFile(p)
	local f = assert(io.open(p, "r"), "cannot open " .. tostring(p))
	local s = f:read("*a")
	f:close()
	return s
end

local function report(label)
	local o = build.calcsTab.mainOutput
	print(string.format("%-28s TotalDPS=%-12.4f SkillTriggerRate=%s",
		label, o.TotalDPS or -1, tostring(o.SkillTriggerRate)))
end

local xmlA, xmlB = readFile(pathA), readFile(pathB)

-- steps 1-2: ground truth for both builds, with the workaround applied
-- (wipe before recalculating) so the printed values are the true ones
loadBuildFromXML(xmlA, "A"); wipeGlobalCache(); build.calcsTab:BuildOutput(); report("A (true values)")
loadBuildFromXML(xmlB, "B"); wipeGlobalCache(); build.calcsTab:BuildOutput(); report("B (true values)")
-- step 3: the bug -- reload A and recalculate DIRECTLY, as headless callers
-- do; the trigger data cached from B leaks into A's outputs
loadBuildFromXML(xmlA, "A"); build.calcsTab:BuildOutput(); report("A (direct recalc, DIRTY)")
-- step 4: the one-line mitigation restores correctness
--wipeGlobalCache(); 
build.calcsTab:BuildOutput(); report("A")

See issue for test builds.

#repo/src # luajit repro.lua builda.xml buildb.xml
Loading main script...
Unicode support detected
Loading passive tree data for version '3.28'...
Removing legacy alternate ascendancies from tree: Primalist, Warden, Warlock
Loading passive tree assets...
Loading passive tree sprite data for version '3.28'...
Processing tree...
Startup time: 0 ms
Uniques loaded
Rares loaded
A (true values)              TotalDPS=5.4331       SkillTriggerRate=0.0089994464747016
B (true values)              TotalDPS=35.0928      SkillTriggerRate=0.058127941857164
A (direct recalc, DIRTY)     TotalDPS=5.4331       SkillTriggerRate=0.0089994464747016
A                            TotalDPS=5.4331       SkillTriggerRate=0.0089994464747016

Paliak and others added 2 commits July 20, 2026 18:13
Signed-off-by: Paliak <91493239+Paliak@users.noreply.github.com>
Co-authored-by: TheCityVault <thecityvault@users.noreply.github.com>
@LocalIdentity LocalIdentity added technical Hidden from release notes bug: behaviour Behavioral differences and removed technical Hidden from release notes labels Jul 20, 2026
@LocalIdentity
LocalIdentity merged commit cef72e7 into PathOfBuildingCommunity:dev Jul 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug: behaviour Behavioral differences

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stale GlobalCache trigger data survives loading a new build when recalculation is invoked directly; produces stable but wrong trigger rates/DPS

2 participants