zebra-spaces: fix worklet-load race that killed self-capture
Fox 2026-06-05 log: "self capture: worklet module load failed" at the
same instant a remote capture for the same publisher succeeded.
Root cause was a check in loadWhisperCaptureWorklet:
if (whisperCaptureWorkletReady || whisperCaptureWorkletLoading)
return Promise.resolve(whisperCaptureWorkletReady);
When TWO calls happen near-simultaneously (one from startSelfCapture,
one from startCaptureForUuid on toggle-on), the second caller sees
whisperCaptureWorkletLoading === true and gets back
Promise.resolve(false). Caller bails. By the time the actual load
finishes, the second caller already gave up.
Fix: cache the loading promise itself and return the same one to
every concurrent caller. They all await the same resolution; both
succeed when the module is ready. On error, the cached promise is
cleared so a later toggle can retry.
After this lands, self-capture should engage on every host that has
transcribe on. Telemetry's selfCap=1 will flip to 1.
This commit is contained in:
parent
af6de11540
commit
8086627086
1 changed files with 14 additions and 8 deletions
|
|
@ -2102,23 +2102,29 @@ registerProcessor('whisper-capture', WhisperCaptureProcessor);
|
|||
`;
|
||||
|
||||
let whisperCaptureWorkletReady = false;
|
||||
let whisperCaptureWorkletLoading = false;
|
||||
let _whisperCaptureLoadPromise = null;
|
||||
/* RACE FIX: previous version returned Promise.resolve(false) for any
|
||||
* SECOND concurrent caller — startSelfCapture and startCaptureForUuid
|
||||
* both fire on toggle-on and the loser got "not ready" instead of
|
||||
* awaiting the in-flight load. Fox 2026-06-05 surfaced this as
|
||||
* "self capture: worklet module load failed." Cache the loading
|
||||
* promise so every caller awaits the same one. */
|
||||
function loadWhisperCaptureWorklet(ctx){
|
||||
if (whisperCaptureWorkletReady || whisperCaptureWorkletLoading) return Promise.resolve(whisperCaptureWorkletReady);
|
||||
whisperCaptureWorkletLoading = true;
|
||||
if (whisperCaptureWorkletReady) return Promise.resolve(true);
|
||||
if (_whisperCaptureLoadPromise) return _whisperCaptureLoadPromise;
|
||||
const blob = new Blob([WHISPER_CAPTURE_WORKLET_CODE], { type: 'application/javascript' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
return ctx.audioWorklet.addModule(url).then(() => {
|
||||
_whisperCaptureLoadPromise = ctx.audioWorklet.addModule(url).then(() => {
|
||||
URL.revokeObjectURL(url);
|
||||
whisperCaptureWorkletReady = true;
|
||||
whisperCaptureWorkletLoading = false;
|
||||
return true;
|
||||
}).catch(e => {
|
||||
URL.revokeObjectURL(url);
|
||||
whisperCaptureWorkletLoading = false;
|
||||
_whisperCaptureLoadPromise = null; /* allow retry on next call */
|
||||
logLine('err', 'whisper-capture worklet load: '+e.message);
|
||||
return false;
|
||||
});
|
||||
return _whisperCaptureLoadPromise;
|
||||
}
|
||||
|
||||
/* Whisper inference runs in a dedicated Web Worker so ONNX Runtime
|
||||
|
|
@ -7420,8 +7426,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');
|
|||
|
||||
<footer style="margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
|
||||
<span id="pi-seal" style="color:#777;cursor:default;user-select:none" title="">page integrity</span> · built <span class="stamp-date">2026-06-05</span><br>
|
||||
md5 <span class="stamp-md5">9aa06e957f35ac7f764fb8c97bb3c634</span><br>
|
||||
sha256 <span class="stamp-sha">46c487137a3aabfca6d136a0164676f4f07d3a727223fce109b42b339dae3eb5</span><br>
|
||||
md5 <span class="stamp-md5">9870220482eb18365ec4f5c8f556d976</span><br>
|
||||
sha256 <span class="stamp-sha">853b11dcfc8b3612fbe452d53df6cec037a125654ff858f79d891855f6396fad</span><br>
|
||||
<span style="color:#bbb">hashes are of this page with these two fields zeroed — to verify, blank them and re-hash</span><br>
|
||||
<span style="color:#bbb">one self-contained file — <strong>save a copy</strong> and verify against these hashes; point at your own servers with ?signal= and ?turncred=, or <a href="host-your-own.html" style="color:#999">host your own community</a></span>
|
||||
</footer>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue