You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Problem (measured on the real 40-project IBS solution, VM disk, 2026-07-14 retests)
Startup runs four I/O sweeps to verify disk caches that are almost always clean: SDI 4,104 stats, FRG 3,016 stats, RefIndex 3,016, plus the open-tab validator pass reads. Two structural findings from the [P4] -> [352-353] -> [352-355] log sequence:
Per-op cost is machine-dependent and does not warm away. The same SDI stat loop measured 97-224ms on a warm dev box and 2,008-6,972ms on an idle VM; run-2-vs-run-1 comparisons showed a see-saw (some phases SLOWER on the second run), i.e. a fresh per-I/O tax per process (AV filter is the prime suspect), not a cold cache that warms. Cold/taxed disk IS the product experience: after boot, after a VSIX update, on customer VMs.
Concurrency multiplies the pain.Perf: SDI startup revalidation (4,104 stats) gates the async validator pass - 7s diagnostics delay on cold/taxed disk #355 moved the SDI sweep off the gating path - and the freed validators + FRG + RefIndex + background SDI sweep then ran SIMULTANEOUSLY: classConstants code actions starved 9-26s (were 150-250ms), FRG went 303ms -> 25-27s, the SDI background sweep took 19-21s vs 7s foreground. On an op-rate-bound disk, parallel sweeps do not overlap waiting - they queue behind each other plus seek/filter overhead. The old serialized startup was an ACCIDENTAL rate limiter; the fix is a deliberate one.
The lever we own is per-operation COUNT and SCHEDULING, not cache warmth.
Design
Part 1 - one sequential background I/O lane
All background sweeps run strictly one at a time, in this order, starting only after the open tab`s async validation pass has completed:
Interactive requests (code actions, F12, hover, lens resolves) are never queued behind the lane - the lane yields to them, not vice versa. This is also the home for the banked "interactive-request priority" item (F12 measured 14.9s queued behind validator storms on 07-13).
Part 2 - freshness tiers keyed off RED path shape
The redirection entries already classify every directory, no heuristics needed:
Volatile tier - project-relative paths (.\genfiles\src, .\classes, .\SharedCode\*, .): the only dirs that change between sessions (appgen regen writes ONLY genfiles\src - confirmed by Mark; git pull; hand edits). Keep per-file mtime checks at startup. Scale: a few hundred files instead of thousands.
Vendor tier - install-rooted paths (macro-derived absolute: %ROOT%\libsrc\win, %ROOT%\Accessory\libsrc\win, images, template) plus the ClarionProperties.xml <libsrc> node dirs: change only when an installer runs. Startup does ONE stat per directory against a stored fingerprint (dir mtime + file count); tripwire fires -> deep-sweep that directory only. Backstops for the in-place-overwrite edge (dir mtime does not change when an existing file is rewritten): a sentinel file check (e.g. equates.clw mtime) and an explicit "Clarion: Refresh Index" command for patch day.
Applies to the SDI sweep first (4,104 -> ~500 stats + ~12 dir stats). FRG/RefIndex files are solution sources = all volatile tier by definition; their win comes from Part 1, not Part 2.
Part 3 - cheap hardening riding along
Cache identity becomes mtime + size (both come from the same stat; strictly stronger) - Mark`s suggestion.
Watch the RED files themselves and invalidate resolution caches on change - the decompiled IDE does exactly this (FileSystemWatcher per RED); we currently reparse only on solution load.
Phasing
A. Sequential background lane (biggest UX win: kills the 9-26s code-action starvation and restores FRG to warm-cache speed)
B. SDI freshness tiers (kills ~3,600 startup stats; needs the volatile/vendor classifier on RedirectionEntry paths + per-dir fingerprints in the SDI disk cache + the Refresh Index command)
C. mtime+size identity + RED-file watcher
Each phase lands via the usual per-issue branch/TDD cycle; A is independently shippable and should go first.
Acceptance
Startup on a cold/taxed disk: no interactive request (code action, F12, hover) starved behind background sweeps; diagnostics-settled time no worse than [352-355]; background sweeps complete without overlapping each other.
SDI startup I/O: per-file stats only for volatile-tier dirs; vendor tier = one stat per dir when fingerprints match.
Environment guidance documented (README/wiki): Defender exclusions for the dev tree + %TEMP%\clarion-extension-* caches.
Context
Design agreed with Mark 2026-07-14 (post-#345/#352/#353/#355 retests; pause called after the [352-355] contention log). Ground truth inputs: his sln + Clarion REDs (F:\TestApps\Direct10Meta\red), the "Redirection System" doc, and the decompiled IDE`s RedirectionFile.cs. Related: #295 (off-thread architecture), #354 (hot-path logging sweep), banked queue items (lens-count reuse, missingIncludes phase-5 memoize, chain-index persistence).
Problem (measured on the real 40-project IBS solution, VM disk, 2026-07-14 retests)
Startup runs four I/O sweeps to verify disk caches that are almost always clean: SDI 4,104 stats, FRG 3,016 stats, RefIndex 3,016, plus the open-tab validator pass reads. Two structural findings from the [P4] -> [352-353] -> [352-355] log sequence:
Per-op cost is machine-dependent and does not warm away. The same SDI stat loop measured 97-224ms on a warm dev box and 2,008-6,972ms on an idle VM; run-2-vs-run-1 comparisons showed a see-saw (some phases SLOWER on the second run), i.e. a fresh per-I/O tax per process (AV filter is the prime suspect), not a cold cache that warms. Cold/taxed disk IS the product experience: after boot, after a VSIX update, on customer VMs.
Concurrency multiplies the pain. Perf: SDI startup revalidation (4,104 stats) gates the async validator pass - 7s diagnostics delay on cold/taxed disk #355 moved the SDI sweep off the gating path - and the freed validators + FRG + RefIndex + background SDI sweep then ran SIMULTANEOUSLY: classConstants code actions starved 9-26s (were 150-250ms), FRG went 303ms -> 25-27s, the SDI background sweep took 19-21s vs 7s foreground. On an op-rate-bound disk, parallel sweeps do not overlap waiting - they queue behind each other plus seek/filter overhead. The old serialized startup was an ACCIDENTAL rate limiter; the fix is a deliberate one.
The lever we own is per-operation COUNT and SCHEDULING, not cache warmth.
Design
Part 1 - one sequential background I/O lane
All background sweeps run strictly one at a time, in this order, starting only after the open tab`s async validation pass has completed:
Interactive requests (code actions, F12, hover, lens resolves) are never queued behind the lane - the lane yields to them, not vice versa. This is also the home for the banked "interactive-request priority" item (F12 measured 14.9s queued behind validator storms on 07-13).
Part 2 - freshness tiers keyed off RED path shape
The redirection entries already classify every directory, no heuristics needed:
.\genfiles\src,.\classes,.\SharedCode\*,.): the only dirs that change between sessions (appgen regen writes ONLY genfiles\src - confirmed by Mark; git pull; hand edits). Keep per-file mtime checks at startup. Scale: a few hundred files instead of thousands.%ROOT%\libsrc\win,%ROOT%\Accessory\libsrc\win, images, template) plus the ClarionProperties.xml<libsrc>node dirs: change only when an installer runs. Startup does ONE stat per directory against a stored fingerprint (dir mtime + file count); tripwire fires -> deep-sweep that directory only. Backstops for the in-place-overwrite edge (dir mtime does not change when an existing file is rewritten): a sentinel file check (e.g. equates.clw mtime) and an explicit "Clarion: Refresh Index" command for patch day.Applies to the SDI sweep first (4,104 -> ~500 stats + ~12 dir stats). FRG/RefIndex files are solution sources = all volatile tier by definition; their win comes from Part 1, not Part 2.
Part 3 - cheap hardening riding along
Phasing
Each phase lands via the usual per-issue branch/TDD cycle; A is independently shippable and should go first.
Acceptance
Context
Design agreed with Mark 2026-07-14 (post-#345/#352/#353/#355 retests; pause called after the [352-355] contention log). Ground truth inputs: his sln + Clarion REDs (F:\TestApps\Direct10Meta\red), the "Redirection System" doc, and the decompiled IDE`s RedirectionFile.cs. Related: #295 (off-thread architecture), #354 (hot-path logging sweep), banked queue items (lens-count reuse, missingIncludes phase-5 memoize, chain-index persistence).