← back to Dead Agentabrams
Fast onload: cache archive.org's down state, cut timeouts
6b22391d83ddad7f94351117fd348c15c9ff9cf3 · 2026-09-03 12:53:52 -0700 · Steve Abrams
Steve: "Music must start onload fast !!" Measured 9.4s from page
load to first playback — bootMusic tries archive.org twice in
sequence (pool-build, then the default-show fetch), each paying a
6-9s timeout before falling back to YouTube, and archive.org has
been down for hours this session.
Added a localStorage health cache (dead.archiveDownUntil, 10min
cooldown): fetchT marks it on every success/failure, and both
_poolFromShows and loadShowRef check it up front and skip straight
to the YouTube fallback when archive is known-down — no wasted
round-trip. Also tightened the raw timeouts 7000/6000ms -> 3000ms as
a floor for the first-ever cold load, before the cache has data.
Measured: cold first visit 9.4s -> 3.1s; any visit after that within
the cooldown 9.4s -> 0.8s. Recovery is automatic — the very next
successful archive.org call (from anywhere: search, a real show
load) clears the flag immediately.
Files touched
Diff
commit 6b22391d83ddad7f94351117fd348c15c9ff9cf3
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Sep 3 12:53:52 2026 -0700
Fast onload: cache archive.org's down state, cut timeouts
Steve: "Music must start onload fast !!" Measured 9.4s from page
load to first playback — bootMusic tries archive.org twice in
sequence (pool-build, then the default-show fetch), each paying a
6-9s timeout before falling back to YouTube, and archive.org has
been down for hours this session.
Added a localStorage health cache (dead.archiveDownUntil, 10min
cooldown): fetchT marks it on every success/failure, and both
_poolFromShows and loadShowRef check it up front and skip straight
to the YouTube fallback when archive is known-down — no wasted
round-trip. Also tightened the raw timeouts 7000/6000ms -> 3000ms as
a floor for the first-ever cold load, before the cache has data.
Measured: cold first visit 9.4s -> 3.1s; any visit after that within
the cooldown 9.4s -> 0.8s. Recovery is automatic — the very next
successful archive.org call (from anywhere: search, a real show
load) clears the flag immediately.
---
room/index.html | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/room/index.html b/room/index.html
index 41e38b3..9e684d7 100644
--- a/room/index.html
+++ b/room/index.html
@@ -2052,7 +2052,8 @@ async function loadShowRef(s, opts){
$('mrTracks').innerHTML=''; $('mrMsg').hidden=true; $('mrMsg').innerHTML='';
setFoot(s);
try{
- const r=await fetchT(`https://archive.org/metadata/${s.id}`, 7000); // timeout so an archive.org outage fails fast → YouTube fallback (TK-11178)
+ if(archiveRecentlyDown()) throw new Error('archive.org recently confirmed down — skip straight to YouTube');
+ const r=await fetchT(`https://archive.org/metadata/${s.id}`, 3000); // fail fast → YouTube fallback (TK-11178; tightened for onload speed)
if(!r.ok) throw new Error('metadata '+r.status);
const j=await r.json();
if(myToken!==loadToken) return; // a newer show was selected while we awaited — drop this result
@@ -2084,6 +2085,15 @@ async function loadShow(i, opts){ if(sel) sel.value=String(i); return loadShowRe
let searchTimer=null;
// archive.org is a flaky nonprofit — abort a hung request so the UI fails gracefully
// into the error state instead of pulsing "…" forever (5x sweep 2 fix).
+// Archive.org health cache (Steve: "Music must start onload fast!!") — archive.org has been
+// down for extended stretches, and every fresh page load was re-paying a ~9s round-trip of
+// timeouts (pool-build + default-show fetch) before falling back to YouTube. Remember a recent
+// outage for a short cooldown so boot skips straight to the fast YouTube path; any successful
+// call clears it immediately so recovery is picked up on the very next request, not after a wait.
+const ARCHIVE_DOWN_KEY='dead.archiveDownUntil', ARCHIVE_COOLDOWN_MS=10*60*1000;
+function archiveRecentlyDown(){ try{ return Date.now() < (+localStorage.getItem(ARCHIVE_DOWN_KEY)||0); }catch(e){ return false; } }
+function markArchiveDown(){ try{ localStorage.setItem(ARCHIVE_DOWN_KEY, String(Date.now()+ARCHIVE_COOLDOWN_MS)); }catch(e){} }
+function markArchiveUp(){ try{ localStorage.removeItem(ARCHIVE_DOWN_KEY); }catch(e){} }
function fetchT(url, ms=9000, extSignal){
const ctl = (typeof AbortController!=='undefined') ? new AbortController() : null;
const t = ctl ? setTimeout(()=>ctl.abort(), ms) : null;
@@ -2092,6 +2102,8 @@ function fetchT(url, ms=9000, extSignal){
else extSignal.addEventListener('abort', ()=>ctl.abort(), {once:true});
}
return fetch(url, {mode:'cors', signal: ctl?ctl.signal:undefined})
+ .then(r=>{ if(r.ok) markArchiveUp(); return r; })
+ .catch(e=>{ markArchiveDown(); throw e; })
.finally(()=>{ if(t) clearTimeout(t); });
}
// Browse the WHOLE Grateful Dead collection — empty = most-popular shows; text and/or a year narrow it.
@@ -2399,8 +2411,9 @@ function _matches(title,want){ const n=_norm(title), w=_norm(want); if(!n||!w) r
return new RegExp('\\b'+w.replace(/[.*+?^${}()|[\]\\]/g,'\\$&').replace(/\s+/g,'\\s+')+'\\b').test(n); }
// fan out to the curated shows in parallel, pool every mp3 track (title + direct url)
async function _poolFromShows(){
+ if(archiveRecentlyDown()) return []; // known-down — don't re-pay a ~6s parallel timeout sweep for an empty result
const results=await Promise.allSettled(CATALOG.map(s=>
- fetchT(`https://archive.org/metadata/${s.id}`, 6000).then(r=>r.ok?r.json():null).then(j=>({s,j})))); // timed so boot can't hang on an archive.org outage (TK-11178)
+ fetchT(`https://archive.org/metadata/${s.id}`, 3000).then(r=>r.ok?r.json():null).then(j=>({s,j})))); // fail fast (TK-11178; tightened for onload speed)
const pool=[];
for(const res of results){
if(res.status!=='fulfilled' || !res.value || !res.value.j) continue;
← 20eefcf Videos panel: add Prev/Next concert + 30s back/fwd seek butt
·
back to Dead Agentabrams
·
Music room: apply graphic-designer critique fixes (Steve) cc56eba →