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>
31 lines
1.2 KiB
Bash
31 lines
1.2 KiB
Bash
#!/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
|