MCPcopy
hub / github.com/stemdeckapp/stemdeck / open

Function open

static/js/job.js:280–333  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

278 let stopped = false;
279
280 const open = () => {
281 const es = new EventSource(`/api/jobs/${jobId}/events`);
282 setEventSource(es);
283
284 es.onmessage = (ev) => {
285 attempt = 0; // any successful frame resets backoff
286 let s;
287 try { s = JSON.parse(ev.data); } catch { return; }
288 // Defer by one tick so synchronous user event handlers (clicks,
289 // input events) always complete before SSE state is applied.
290 setTimeout(() => {
291 applyState(s);
292 if (TERMINAL_STATUSES.has(s.status)) {
293 stopped = true;
294 es.close();
295 setEventSource(null);
296 }
297 }, 0);
298 };
299
300 es.onerror = async () => {
301 if (stopped) return;
302 es.close();
303 setEventSource(null);
304
305 // Probe REST once before declaring failure -- handles dev-server
306 // reloads and brief network blips where the job is actually fine.
307 try {
308 const s = await probeJob(jobId);
309 if (TERMINAL_STATUSES.has(s.status)) {
310 stopped = true;
311 return;
312 }
313 } catch (err) {
314 if (err.message === "Job no longer exists on the server") {
315 stopped = true;
316 showError(err.message);
317 setSubmitProcessing(false);
318 return;
319 }
320 // Network down -- fall through to backoff.
321 }
322
323 attempt += 1;
324 if (attempt > 6) {
325 // SSE gave up — activate REST polling as the fallback.
326 startJobPolling(jobId);
327 return;
328 }
329 // 0.5s, 1s, 2s, 4s, 8s, 16s
330 const delay = 500 * Math.pow(2, attempt - 1);
331 setTimeout(() => { if (!stopped) open(); }, delay);
332 };
333 };
334
335 open();
336}

Callers 1

connectEventsFunction · 0.70

Calls 6

setEventSourceFunction · 0.90
applyStateFunction · 0.85
probeJobFunction · 0.85
setSubmitProcessingFunction · 0.85
startJobPollingFunction · 0.85
showErrorFunction · 0.70

Tested by

no test coverage detected