Skip to content

Lite: an upgraded install merges new default ignored waits into the user's list once - #4931

Merged
erikdarlingdata merged 3 commits into
devfrom
fix/lite-ignored-waits-upgrade
Oct 2, 2026
Merged

erikdarlingdata merged 3 commits into
devfrom
fix/lite-ignored-waits-upgrade

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Refs #4884

What was wrong

#4884 added RBIO_COMM_RETRY and SQP_STATS_REPORTING to the default ignored waits. Lite reads config/ignored_wait_types.json from the per-user data folder first, and ConfigSeeder.SeedMissing copies the bundled file only when the per-user one is missing. An install upgraded from an earlier release already has the file, so it never received the two names. Those installs kept collecting, showing and analysing the two waits. Only fresh installs got the fix.

The fix

At startup, right after SeedMissing and before anything calls IgnoredWaitTypes.Load(), Lite runs IgnoredWaitTypes.MergeNewDefaults(bundled, user).

  • The per-user file gets a new top-level seen_defaults array beside ignored_waits. It records the bundled defaults the file has already been offered.
  • A file without seen_defaults was written by v3.8.0 or earlier. The bundled list is identical, 124 names, in every release from v1.0.0 through v3.8.0, so such a file has seen exactly IgnoredWaitTypes.V380Defaults (that list, compiled in). Any default added later, in 3.9.0 or a future release, differs from it, so an install that skips releases still gains every new default.
  • bundled - seen is appended to ignored_waits (case-insensitive, skipping names already there), and seen_defaults becomes seen + bundled.
  • The pure core is TryMergeNewDefaults(JsonObject, IReadOnlyCollection<string>, out JsonObject, out string?); MergeNewDefaults is the file wrapper.

What stays the user's

  • A default the user removed stays removed, including one of the two new names removed after the merge (it is in seen_defaults).
  • Their own additions and their ordering stay; new names are appended.
  • Every other property in the file survives (the file is edited as a JsonObject, not a typed model).
  • The file is rewritten only when something changed, through a .tmp file and File.Move(..., overwrite: true), keeping the file's line endings and trailing newline. The rewrite is indented two spaces, one name per line, and drops a UTF-8 byte-order mark; Load reads either form. A second start is a no-op: same bytes, same last-write time.
  • A fresh install's seeded copy already lists both names, so its one write only adds seen_defaults.
  • Any failure (a missing bundle, an unreadable, locked or malformed user file) leaves the user's file exactly as it was, and startup never fails. A file whose ignored_waits or seen_defaults is not a list of strings is left alone with a warning naming which. A malformed file is never overwritten.
  • One edge: an install that started fresh on a pre-release build carrying Wait names lose their trailing space, and two Hyperscale timer waits are ignored #4884 has both names and no seen_defaults. If that user then removed one of the two, it is added back once.

Darling needs no change

Darling's collectors use the compiled-in IgnoredWaitDefaults.All (DarlingCollectorRunner.cs, both collector option sites). There is no per-store or per-user override and no migration that stores an ignored list, so an upgraded Darling store gets the new names with the new binary.

Lite analysis

The wait-profile fact read in DuckDbFactCollector.Waits.cs does not apply the ignored list at read time; it reads whatever was stored. The merge stops new rows for the two waits on upgraded installs (collection) and hides old rows in the wait-stats tab at once (display uses IgnoredWaitTypes.Load()). Rows already stored age out of the analysis window.

Pins

Lite.Tests/IgnoredWaitTypesUpgradeTests.cs, over the pure function and the file wrapper in a temp directory:

  • V380Defaults equals v3.8.0's bundled list name for name, and the current bundle carries all of it plus the two;
  • a v3.8.0-shaped file gains exactly the two names and gets seen_defaults;
  • a file with no seen_defaults, against a bundle carrying a future name too, gains all three;
  • a removed old default (CHECKPOINT_QUEUE) stays removed while the two are added;
  • a user-added wait stays, in place;
  • a new default already present (any case) is not duplicated;
  • a new default removed after the merge stays removed on the next start;
  • a later release's default is added once when seen_defaults exists;
  • unknown properties survive;
  • the second start writes nothing (bytes and last-write time unchanged), and no .tmp is left;
  • a malformed file, and a valid file against a bundle with no ignored_waits, are byte-identical afterwards;
  • five refused shapes return false with the input untouched and a reason;
  • a missing user file is not created;
  • a freshly seeded copy of the real bundle writes once (keeping its 126 waits and gaining seen_defaults), then not again.

The tests commit does not compile on dev (MergeNewDefaults and TryMergeNewDefaults do not exist yet).

Tests run

  • Lite.Tests and Darling.Tests build with 0 warnings and 0 errors.
  • Lite.Tests: IgnoredWaitTypesUpgradeTests, ConfigSeederTests, SharedCollectorDefaultsPinTests and DataRootMigrationTests, 38 passing at the first fix commit; CI's Lite shards run the whole suite.
  • Darling.Tests in-process: the T-SQL convention, doc-comment and repo-file guards, all passing.
  • The file wrapper against the real v3.8.0 file: it merged once (CRLF and trailing newline kept, 126 waits, 126 seen), the second call returned false, and a truncated file was left untouched with a warning.

CHANGELOG

None: this amends #4884's Fixed entry to cover upgraded installs.

@erikdarlingdata
erikdarlingdata marked this pull request as ready for review October 2, 2026 01:30
@erikdarlingdata
erikdarlingdata merged commit 88b36f4 into dev Oct 2, 2026
17 of 18 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/lite-ignored-waits-upgrade branch October 2, 2026 01:31
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