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.
This commit is contained in:
1 parent
7057a5999e
commit
cf54ff8b45
2 files changed
+19
-9
No files matched your search
+16
-9
@@ -159,14 +159,11 @@ async function ensureFreshBuild() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(() => {
|
||||||
ensureFreshBuild()
|
ensureFreshBuild()
|
||||||
await Promise.all([
|
|
||||||
loadStrategies(),
|
// Set up the socket and the polling fallback first, so a failing initial
|
||||||
loadPresets(),
|
// fetch can never prevent them (that left the badge stuck on "connecting").
|
||||||
api.getStatus().then((s) => (status.value = s)),
|
|
||||||
refreshAll(),
|
|
||||||
])
|
|
||||||
socket = api.openSocket({
|
socket = api.openSocket({
|
||||||
onMessage: handleMessage,
|
onMessage: handleMessage,
|
||||||
onOpen: () => {
|
onOpen: () => {
|
||||||
@@ -185,9 +182,19 @@ onMounted(async () => {
|
|||||||
graceTimer = setTimeout(() => {
|
graceTimer = setTimeout(() => {
|
||||||
if (!connected.value) pollingFallback.value = true
|
if (!connected.value) pollingFallback.value = true
|
||||||
}, 6000)
|
}, 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.
|
// Poll fast enough that the UI feels live even when it is the only channel.
|
||||||
pollTimer = setInterval(refreshAll, 3000)
|
pollTimer = setInterval(() => refreshAll().catch(() => {}), 3000)
|
||||||
statusTimer = setInterval(() => api.getStatus().then((s) => (status.value = s)), 3000)
|
statusTimer = setInterval(
|
||||||
|
() => api.getStatus().then((s) => (status.value = s)).catch(() => {}),
|
||||||
|
3000,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export function openSocket({ onMessage, onOpen, onClose, onError }) {
|
|||||||
if (closed) return
|
if (closed) return
|
||||||
let opened = false
|
let opened = false
|
||||||
let reported = false
|
let reported = false
|
||||||
|
console.debug('[ws] connecting to', url)
|
||||||
socket = new WebSocket(url)
|
socket = new WebSocket(url)
|
||||||
|
|
||||||
// Report at most one failure per attempt (Safari often fires error *and*
|
// 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
|
opened = true
|
||||||
clearTimeout(openTimeout)
|
clearTimeout(openTimeout)
|
||||||
attempt = 0
|
attempt = 0
|
||||||
|
console.debug('[ws] open')
|
||||||
onOpen?.()
|
onOpen?.()
|
||||||
}
|
}
|
||||||
socket.onmessage = (event) => onMessage?.(JSON.parse(event.data))
|
socket.onmessage = (event) => onMessage?.(JSON.parse(event.data))
|
||||||
socket.onclose = (event) => {
|
socket.onclose = (event) => {
|
||||||
clearTimeout(openTimeout)
|
clearTimeout(openTimeout)
|
||||||
|
console.debug('[ws] close', event.code, event.reason)
|
||||||
onClose?.()
|
onClose?.()
|
||||||
if (!opened) {
|
if (!opened) {
|
||||||
// 1008 = policy violation (token rejected); 1006 = abnormal close.
|
// 1008 = policy violation (token rejected); 1006 = abnormal close.
|
||||||
|
|||||||
Reference in new issue
Block a user