Panel prowadzenia dociaga stan po ponownym polaczeniu
Deploy PROD / deploy (push) Successful in 25s

WebSocket nie ma historii: zdarzenie wyslane, gdy panel byl rozlaczony,
przepada bezpowrotnie. Panel wracal wiec ze stanem sprzed zerwania i pokazywal
go jako aktualny.

Zdarzylo sie to realnie: backend zrestartowal sie przy wdrozeniu, uczestnik
poprosil o glos w czasie, gdy panel byl rozlaczony, a prowadzacy widzial
"Nikt nie prosi o glos" przy zgloszeniu czekajacym juz kilkadziesiat sekund.
Zgloszenie pojawilo sie dopiero po odswiezeniu strony. Objaw myli, bo panel
wyglada na dzialajacy, a jedyna wskazowka jest znikniecie znacznika
"polaczono".

Rozlaczenie nie jest sytuacja wyjatkowa: wystarczy restart backendu, chwilowa
utrata sieci albo uspienie laptopa. `reconnectDelay` wznawial polaczenie, ale
nikt nie dociagal tego, co umknelo w miedzyczasie.

`onConnect` odswieza teraz kolejke glosu, czat z pytaniami oraz tryby
mikrofonu i wideo. Przy pierwszym polaczeniu jest to zapytanie nadmiarowe,
przy kazdym nastepnym jedyne zrodlo prawdy.

`refetch` sa pominiete w zaleznosciach efektu swiadomie: TanStack Query daje
je stabilne, a dopisanie ich przelaczaloby WebSocket przy kazdym odswiezeniu
danych, czyli powodowalo dokladnie ten problem, ktoremu ta zmiana zapobiega.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 13:55:36 +02:00
parent 2e1cb89fc6
commit b96cf8d07d
@@ -172,6 +172,29 @@ export function HostConsolePage() {
reconnectDelay: 4000, reconnectDelay: 4000,
onConnect: () => { onConnect: () => {
setConnected(true) setConnected(true)
/*
* DOCIAGNIECIE STANU PO KAZDYM POLACZENIU
*
* WebSocket nie ma historii: zdarzenie wyslane, gdy panel byl
* rozlaczony, przepada bezpowrotnie. Przy pierwszym polaczeniu to bez
* znaczenia (dane przyszly zapytaniami), ale przy KAZDYM NASTEPNYM
* panel wracalby ze stanem sprzed zerwania i pokazywal go jako
* aktualny.
*
* Zdarzylo sie to realnie: backend zrestartowal sie przy wdrozeniu,
* uczestnik poprosil o glos w czasie, gdy panel byl rozlaczony,
* a prowadzacy widzial "Nikt nie prosi o glos" przy zgloszeniu
* czekajacym juz kilkadziesiat sekund. Zgloszenie pojawilo sie
* dopiero po odswiezeniu strony.
*
* Rozlaczenie nie jest przy tym sytuacja wyjatkowa: wystarczy restart
* backendu, chwilowa utrata sieci albo uspienie laptopa.
*/
void loadSpeakQueue()
void initial.refetch()
void webinar.refetch()
stomp.subscribe(`/topic/webinars/${id}/moderation`, (message: IMessage) => { stomp.subscribe(`/topic/webinars/${id}/moderation`, (message: IMessage) => {
const event = JSON.parse(message.body) as { kind: string; payload: InteractionView } const event = JSON.parse(message.body) as { kind: string; payload: InteractionView }
apply(event) apply(event)
@@ -236,6 +259,14 @@ export function HostConsolePage() {
return () => { return () => {
void stomp.deactivate() void stomp.deactivate()
} }
/*
* `initial.refetch` i `webinar.refetch` sa POMINIETE w zaleznosciach
* swiadomie. TanStack Query daje je stabilne, a dopisanie ich tutaj
* przelaczaloby WebSocket przy kazdym odswiezeniu danych: polaczenie
* zrywaloby sie samo i gubilo zdarzenia, czyli dokladnie to, czemu ten
* efekt ma zapobiegac.
*/
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [id, loadSpeakQueue]) }, [id, loadSpeakQueue])
async function act(interactionId: number, action: string, body?: unknown) { async function act(interactionId: number, action: string, body?: unknown) {