Blog

Sådan holder vi chatten i live, når telefonen sover

Mythex' agent kan arbejde i flere minutter på én anmodning, og du følger måske med fra en telefon — som låser, skifter app og skifter netværk, mens den arbejder. To fejl gjorde det galt. I den ene behandlede chatten hvert signal om „siden er synlig igen“ som bevis for, at forbindelsen var død, og løb i ring, indtil den stod og viste „Connecting…“. I den anden fik en telefon, der havde sovet gennem det første svar i en ny chat, kun de første stykker af det tilbage, indtil man opdaterede siden manuelt. Begge er rettet.

Sådan følger chatten et kørende forløb

Mens agenten arbejder, holder chatten en stream åben fra vores servere: hvert trin — en tanke, et værktøjskald, et stykke af svaret — kommer ind som en hændelse. Hvis streamen falder fra, genopretter chatten forbindelsen, og serveren afspiller de seneste hændelser fra en buffer, der holder de sidste 120 sekunder. Når forløbet er slut, beder chatten også serveren om den gemte historik og afstemmer det, den viste, mod det, der blev gemt. Dette sidste trin fanger alt, streamen gik glip af.

For at skelne en levende forbindelse fra en død, når der ikke sker noget, sender serveren et lille „ping“ hvert 15. sekund.

Fejl 1: at vågne dræbte en sund stream

Browsere fortæller en side, når den bliver synlig igen: efter et faneskifte, efter at skærmen låses op. Vi brugte det som et signal om at tjekke forbindelsen — og i praksis til at afbryde streamen og genoprette forbindelsen, under antagelsen om, at den var død, mens den var skjult.

På telefoner og i indlejrede browsere udløses disse hændelser langt oftere, end streams dør — ved hvert faneskifte, hver oplåsning, og i nogle indlejrede browsere hvert par sekunder. Hver af dem afbrød en fuldt sund stream. Chatten genoprettede forbindelsen, afspillede, blev afbrudt igen og endte med at stå på „Connecting…“. Så meldte den, at forløbet var slut, mens agenten stadig arbejdede.

Rettelsen: bedøm streamen ud fra, om den taler

Chatten registrerer nu, hvornår hver projekts stream sidst modtog noget overhovedet — hændelser og 15-sekunders-pings lige meget. Et „synlig igen“-signal afbryder kun en stream, der har været stille i 25 sekunder: længere end ping-intervallet plus et langsomt netværksled, så en levende stream aldrig kommer i betragtning. Tests bekræfter, at et ping tæller som tegn på liv, og at en stream, der lige har pinget, ikke behandles som død.

Reglen, vi tog med os: en sides synlighed siger noget om siden, ikke om netværksforbindelsen. Spørg forbindelsen.

Fejl 2: halvt svar, efter telefonen vågnede

Denne kunne vi reproducere hver gang i iOS-simulatoren:

  1. Start en ny chat og send en anmodning, der tager et stykke tid.
  2. Lad telefonen sove gennem byggeriet.
  3. Kom tilbage, efter forløbet er færdigt, og to-minutters replay-bufferen er udløbet.

Chatten viste de første få blokke af svaret, markeret som færdige — og blev sådan, indtil man opdaterede siden.

Hvorfor

En ny chat har ingen tråd — den gemte samtale — før den første besked opretter en. Det sker inde i send-funktionen, efter at send allerede havde fanget afstemningstrinnet, som stadig troede, at der ikke var nogen tråd. Så ved slutningen af det første forløb i en ny chat så afstemningen ingen tråd og vendte stille tilbage uden at hente noget.

Normalt bemærkede ingen det, fordi streamen allerede havde leveret hele forløbet. Men en telefon, der sov gennem forløbet og vågnede efter, at 120-sekunders replay-bufferen var udløbet, kunne ikke hente de manglende hændelser fra streamen — og afstemningen, der skulle have udfyldt hullet, var aldrig blevet kørt.

Rettelsen

  • Send fortæller afstemningen, hvilken tråd forløbet hører til, så det første forløb i en ny chat afstemmes som alle andre. Hvis du har åbnet en anden chat, når svaret kommer tilbage, kasseres resultatet i stedet for at blive vist det forkerte sted.
  • En mislykket afstemning forsøges igen. En telefon, der vågner på en dårlig forbindelse, kan opdage, at forløbet er slut, og så ikke kunne hente det. Det huskes nu, og chatten spørger igen, når fanen vises igen, eller netværket kommer tilbage.
  • „Worked for“ er ærlig. Hvert svar viser, hvor længe agenten arbejdede. Hvis fanen aldrig så serverens besked om forløbets afslutning, udfyldte den tidligere det selv med sit eget ur — som løb fra Send, indtil telefonen vågnede, inklusive tiden væk. Tallet er nu markeret som et estimat og erstattes af den gemte varighed, når historikken kommer.

Hvad vi tog med

  • Test på den enhed, folk faktisk bruger, og på den måde de bruger den. Begge fejl lå i mellemrummet mellem „en stream, der virker“ og „en telefon i lommen“.
  • En reserve, der aldrig kører, er ingen reserve. Afstemningstrinnet fandtes netop til at fange dette tilfælde, og det blev stille sprunget over.
  • Prøv også genoprettelsen igen. Øjeblikket, en telefon vågner, er ofte, når dens forbindelse er på sit dårligste.
  • Vis ikke et gæt som et faktum. En varighed fra det forkerte ur er værre end ingen; mærk den eller erstat den.

Det samme arbejde ryddede også op i et par ting, du vil se, mens et forløb kører: shell-trin er mærket med den kommando, der udfører arbejdet, i stedet for cd; skærmbilleder i chatten holder det øverste venstre hjørne af siden og passer til kolonnen; og et nyt projekt får sit genererede navn uden en opdatering.

Hvis du bygger din egen app til telefoner, dækker vores guides til at bygge en mobilvenlig webapp og native apps vs. progressive web apps det grundlæggende. Mere om selve chatten findes i chat-dokumentationen.

Mythex · Pricing · Byg hvad som helst med AI · Skabeloner til websites og apps · Mythex sammenlignet · Ordliste for app-bygning med AI · Gratis værktøjer til app-bygning med AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)