Keep panel loaders across plugin changes so the OSD loads once (#13439)
Every plugin change handed the panel Instantiator a fresh array, which rebuilds every panel. The panels were rebuilt four times in the first 700ms of startup, each rebuild starting a new asynchronous load of every keepLoaded panel while the last was still in flight. Under load two OSDs could run at once, each registering the osd IPC handler: the runtime smoke test's intermittent "another handler is registered for target osd". The entries now live in a ListModel synced in place. A panel whose plugin still loads the same way keeps its loader, so startup adds each panel once, and a full plugin reload still clears the model to rebuild from fresh code. Under a six-core busy load the smoke test hit the duplicate in 1 of 5 runs on quattro and in none of 10 with this change. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5929a9b80c
commit
0066ea216b
2 files changed
+77
-11
No files matched your search
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
run_node_test <<'JS'
|
||||
const fs = require('fs')
|
||||
const shellQml = fs.readFileSync(path.join(root, 'shell/shell.qml'), 'utf8')
|
||||
|
||||
// Handing the Instantiator a fresh array rebuilt every panel on each plugin
|
||||
// change, several times during startup, so a keepLoaded panel such as the OSD
|
||||
// could load twice at once and register its IPC handler twice.
|
||||
assert(
|
||||
/Instantiator \{\s*model: panelEntryModel/.test(shellQml) && !shellQml.includes('panelEntries'),
|
||||
'panel loaders come from a model synced in place, not a reassigned array'
|
||||
)
|
||||
assert(
|
||||
/if \(next && next\.kind === row\.entryKind && next\.keepLoaded === row\.keepLoaded && next\.sourceUrl === row\.sourceUrl\) \{\s*delete wanted\[row\.pluginId\]/.test(shellQml),
|
||||
'a panel whose plugin still loads the same way keeps its loader'
|
||||
)
|
||||
assert(
|
||||
/function unloadPanels\(\) \{[\s\S]*?panelEntryModel\.clear\(\)/.test(shellQml),
|
||||
'a full plugin reload still rebuilds every panel from fresh code'
|
||||
)
|
||||
assert(
|
||||
(shellQml.match(/shell\.syncPanelEntries\(\)/g) || []).length === 2,
|
||||
'plugin changes and finished scans sync the panel entries'
|
||||
)
|
||||
JS
|
||||
Reference in new issue
Block a user