fix(webui): load mobile-menu.js; prune orphaned task queue entries
Both found in a user's console log. 1. ReferenceError: setupMobileMenu is not defined (dashboard.js:98) core/topbar/js/mobile-menu.js defines that global, and index.html never loaded it. dashboard.js called it unguarded as the FIRST line of setupEventListeners, so dashboard init threw every page load and took loadInstalledApps() with it — and the burger menu was dead on mobile. system-loader already guarded its own call with a typeof check, which is why this survived unnoticed. Loads the script (before dashboard.js) and guards the call, so optional nav chrome can never take down the page below it again. 2. Endless 404s on /api/tasks/<id> for tasks that no longer exist queue.json is append-only from the enqueue side and nothing ever pruned it, so any task file removed afterwards left an id the WebUI re-fetched forever, one 404 per poll per orphan. Adds cleanupOrphanQueueEntries to the idle housekeeping pass: entries with no task file are dropped and logged. Self-heals existing strays. (Provoked by my own clean-up of two test tasks earlier in this session, but the gap is real and predates it.) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
5e06e77d7f
commit
07daa7555a
@ -95,7 +95,14 @@ async function populateDashboardServiceButtons(installedApps) {
|
||||
|
||||
// Setup event listeners
|
||||
function setupEventListeners() {
|
||||
setupMobileMenu();
|
||||
// Guarded like system-loader's mobile-menu component: this is a nav nicety,
|
||||
// and an unguarded call meant a missing/reordered script took the dashboard's
|
||||
// app list down with it. Never let optional chrome break the page below it.
|
||||
if (typeof setupMobileMenu === 'function') {
|
||||
setupMobileMenu();
|
||||
} else {
|
||||
console.warn('setupMobileMenu not available — mobile drawer disabled');
|
||||
}
|
||||
loadInstalledApps();
|
||||
}
|
||||
|
||||
|
||||
@ -100,6 +100,12 @@
|
||||
<script src="/core/ui-state/js/dismissible.js"></script>
|
||||
<script src="/core/overlays/js/eo-modal.js"></script>
|
||||
<script src="/core/tasks/js/task-refresh-coordinator.js"></script>
|
||||
<!-- Defines the global setupMobileMenu(), which dashboard.js calls from
|
||||
setupEventListeners() and system-loader registers as a component. It was
|
||||
never loaded here, so dashboard init died on a ReferenceError at that
|
||||
call — taking loadInstalledApps() with it — and the burger menu was dead
|
||||
on mobile. Must come before dashboard.js. -->
|
||||
<script src="/core/topbar/js/mobile-menu.js"></script>
|
||||
<script src="/components/dashboard/js/dashboard.js"></script>
|
||||
<script src="/core/boot/js/system-loader.js"></script>
|
||||
<script src="/core/loading/js/loading-ui.js"></script>
|
||||
|
||||
@ -492,6 +492,33 @@ dispatchSpecific() {
|
||||
# HOUSEKEEPING
|
||||
# ============================================================================
|
||||
|
||||
# Drop queue entries whose task file no longer exists. queue.json is append-only
|
||||
# from the enqueue side, so any task file removed afterwards — by housekeeping, a
|
||||
# manual clean-up, a restore — leaves an id behind that the WebUI keeps fetching
|
||||
# forever, one 404 per poll per orphan. Nothing else prunes it, so it only ever
|
||||
# grows. Cheap: a no-op unless an id has no file.
|
||||
cleanupOrphanQueueEntries() {
|
||||
local queue="$TASK_DIR/queue.json"
|
||||
[[ -f "$queue" ]] || return 0
|
||||
command -v jq >/dev/null 2>&1 || return 0
|
||||
|
||||
local ids orphans=() id
|
||||
ids=$(jq -r '.[]?' "$queue" 2>/dev/null) || return 0
|
||||
[[ -z "$ids" ]] && return 0
|
||||
while IFS= read -r id; do
|
||||
[[ -z "$id" ]] && continue
|
||||
[[ -f "$TASK_DIR/${id}.json" ]] || orphans+=("$id")
|
||||
done <<< "$ids"
|
||||
(( ${#orphans[@]} == 0 )) && return 0
|
||||
|
||||
local filtered
|
||||
filtered=$(jq -c --argjson drop "$(printf '%s\n' "${orphans[@]}" | jq -R . | jq -cs .)" \
|
||||
'[ .[] | select(. as $i | $drop | index($i) | not) ]' "$queue" 2>/dev/null) || return 0
|
||||
[[ -n "$filtered" ]] || return 0
|
||||
printf '%s' "$filtered" | runFileWrite "$queue"
|
||||
logInfo "Pruned ${#orphans[@]} orphaned queue entr$( (( ${#orphans[@]} == 1 )) && echo y || echo ies ): ${orphans[*]}"
|
||||
}
|
||||
|
||||
cleanupZeroByteFiles() {
|
||||
# Use the bash builtin `-s` (file size > 0) instead of forking `stat` per
|
||||
# file — at 100+ task files the stat fork was a measurable share of the
|
||||
@ -596,6 +623,7 @@ mainLoop() {
|
||||
recoverOrphans
|
||||
dispatchPending
|
||||
cleanupZeroByteFiles
|
||||
cleanupOrphanQueueEntries
|
||||
maybeRegenPoll
|
||||
fi
|
||||
done
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user