Compare commits

..
2 Commits
Author SHA1 Message Date
matitos fedcd07ffd Don't let a failing initial fetch block the socket/polling fallback
CI/CD / backend (push) Successful in 5m32s
CI/CD / frontend (push) Successful in 5m7s
CI/CD / build (push) Successful in 20s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 40s
2026-09-21 15:57:51 +00:00
matitos cf54ff8b45 Don't let a failing initial fetch block the socket/polling fallback
onMounted awaited the initial REST calls before setting up the socket and the
6s polling fallback, so any rejected request aborted the handler and left the
badge stuck on "connecting". Set up the socket and fallback first, make the
initial loads best-effort, and log [ws] connect/open/close for debugging.
2026-09-21 15:57:50 +00:00
2 changed files with 19 additions and 9 deletions

No files matched your search

+16 -9
View File
@@ -159,14 +159,11 @@ async function ensureFreshBuild() {
}
}
onMounted(async () => {
onMounted(() => {
ensureFreshBuild()
await Promise.all([
loadStrategies(),
loadPresets(),
api.getStatus().then((s) => (status.value = s)),
refreshAll(),
])
// Set up the socket and the polling fallback first, so a failing initial
// fetch can never prevent them (that left the badge stuck on "connecting").
socket = api.openSocket({
onMessage: handleMessage,
onOpen: () => {
@@ -185,9 +182,19 @@ onMounted(async () => {
graceTimer = setTimeout(() => {
if (!connected.value) pollingFallback.value = true
}, 6000)
// Initial loads are best-effort; the intervals below keep retrying.
api.getStatus().then((s) => (status.value = s)).catch(() => {})
refreshAll().catch(() => {})
loadStrategies().catch(() => {})
loadPresets().catch(() => {})
// Poll fast enough that the UI feels live even when it is the only channel.
pollTimer = setInterval(refreshAll, 3000)
statusTimer = setInterval(() => api.getStatus().then((s) => (status.value = s)), 3000)
pollTimer = setInterval(() => refreshAll().catch(() => {}), 3000)
statusTimer = setInterval(
() => api.getStatus().then((s) => (status.value = s)).catch(() => {}),
3000,
)
})
onUnmounted(() => {
+3
View File
@@ -48,6 +48,7 @@ export function openSocket({ onMessage, onOpen, onClose, onError }) {
if (closed) return
let opened = false
let reported = false
console.debug('[ws] connecting to', url)
socket = new WebSocket(url)
// Report at most one failure per attempt (Safari often fires error *and*
@@ -72,11 +73,13 @@ export function openSocket({ onMessage, onOpen, onClose, onError }) {
opened = true
clearTimeout(openTimeout)
attempt = 0
console.debug('[ws] open')
onOpen?.()
}
socket.onmessage = (event) => onMessage?.(JSON.parse(event.data))
socket.onclose = (event) => {
clearTimeout(openTimeout)
console.debug('[ws] close', event.code, event.reason)
onClose?.()
if (!opened) {
// 1008 = policy violation (token rejected); 1006 = abnormal close.