Ako zachytit ukoncenie JS Web Workeru?

hknmtt

  • ***
  • 154
    • Zobrazit profil
    • E-mail
Ako zachytit ukoncenie JS Web Workeru?
« kdy: Dnes v 14:58:33 »
Web worker ma connect event ale uz nema closed event. Mam shared worker ktory ma websocket spojenie pre notifikacie, ale ak mam napriklad iba jedno okno otvorene a refreshnem stranku, tak to zabije worker a znovu ho spusti. Problem je, ze worker neodosle cez websocket close event a teda spojenie neuzavrie "cisto". A musim potom cakat nejaky cas, kym mi backend timeoutne stare spojenie a umozni nadviazat nove spojenie.

Je mozne nejak zaznamenat nieco ako "beforeunload" event v web workeroch a vykonat tak "cistiace" prace pred tym nez ich prehliadac zabije? A musi to byt v workeri, nemoze ist o vyuzitie broadcast kanalu a poslat info workeru z prehliadacu, lebo pri shared workeroch by som si tak zabil worker napriek tomu ze mozem mat otvorene viacej zaloziek a worker nema dovod byt zatvoreny.


Re:Ako zachytit ukoncenie JS Web Workeru?
« Odpověď #1 kdy: Dnes v 17:59:52 »
Bohužiaľ, v Shared Workers ani v bežných Web Workers neexistuje žiadna natívna udalosť typu beforeunload alebo iná udalosť, ktorá by sa spúšťala tesne pred ich ukončením. Akonáhle posledné spojenie (port) k Shared Workeru zanikne, prehliadač jednoducho ukončí jeho beh bez nejakej "poslednej šance" na vykonanie čistiacich operácií z jeho vnútra.

Dôvody a detaily:

Shared Worker životný cyklus:
Shared Worker je udržiavaný nažive pokiaľ existuje aspoň jeden otvorený komunikačný kanál (port) z niektorej zo stránok. Ak máte napríklad dve otvorené karty a obe sú pripojené k rovnakému Shared Workeru, worker beží. Ak jednu kartu zavriete alebo refreshnete, jej porty sa ukončia, no Shared Worker pokračuje v behu, pokiaľ druhá karta je stále pripojená. Ak ale zatvoríte či refreshnete poslednú kartu, ktorá ho používa, Shared Worker zanikne.

Neexistencia "cleanup" eventov v workeroch:
Na rozdiel od hlavného okna (Window) v prehliadači, kde existujú udalosti ako beforeunload či unload, workery (či už Dedicated alebo Shared) takéto mechanizmy nemajú. Dôvodom je, že workery bežia v izolovanom vlákne a ich ukončenie je riadené zo strany prehliadača bez explicitného upozornenia workerov.

Prečo to nejde len vo workeri?
Vývojári bežne riešia „čistenie“ websocketového spojenia alebo iné cleanup akcie pri udalostiach na strane hlavnej stránky – napr. pri beforeunload odoslať do workera správu na uzavretie websocketu. Ak to však striktne nechcete robiť z hlavnej stránky, potom vám v rámci API Shared Workeru neostáva žiadna priama cesta. Worker nevie "sám od seba", že bude ukončený – on jednoducho skončí, keď niet žiadnych portov.

Možné obídenie problému (workaround):

Nepriame signály: Aj keď to nechcete, najčastejšie riešenie je využitie rozhrania medzi stránkou a workerom. Pri beforeunload vo Window odoslať do Shared Workera správu v štýle "odhlasujem sa, uzavri websocket". Ak je to posledný port, tak worker vykoná cleanup pred ukončením.

Timeout / Heartbeat mechanizmus vo workeri: Môžete vo workeri implementovať mechanizmus, ktorý periodicky kontroluje počet otvorených spojení (portov) a pokiaľ zistí, že žiadne nie sú (t.j. odpojí sa posledný port), tak uzavrie websocket. Keďže po odpojení posledného portu už worker žije len veľmi krátko, je isté, že s týmto timeoutom/heartbeatom bude code spustený predtým, než browser worker zruší. Toto však môže byť nespoľahlivé, ak browser ukončí worker príliš promptne – závisí to od implementácie prehliadača. Niektoré prehliadače worker ukončujú takmer okamžite, iné dávajú "pár milisekúnd navyše". Tento prístup nie je 100% garantovaný.

Architektonické úpravy backendu: Ak viete zmeniť správanie na strane servera, môžete upraviť logiku tak, aby "stare" spojenia po novom pripojení od toho istého klienta boli ihneď invalidované. Teda ak sa znova prihlási rovnaký klient s rovnakou identitou, staré spojenie sa na serveri ukončí. Tým vyriešite problém s čakaním na timeout.

hknmtt

  • ***
  • 154
    • Zobrazit profil
    • E-mail
Re:Ako zachytit ukoncenie JS Web Workeru?
« Odpověď #2 kdy: Dnes v 18:35:24 »
Problem notifikacie workeru z okna je ten, ze workery nemaju ponatie o pocte otvorenych okien. To je vecny problem ktory sa riesi roznymy vychytavkami, no ziadna nestoji moc za to. Preto som chcel aby sa to riesilo priamo v workeri, ale ked to nejde tak to nejde. Sudruhovia z gulagu predsa vedia najlepsie.