Steven
Steven5 min lugemist

Kuidas voogedastada reaalajas raportit ilma virvenduseta

Kui koosolek lõpeb, täitub GeekBye kokkuvõte nüüd reaalajas, selle asemel et sundida sind spinnerit vahtima. Selleks et voogedastuse liides tunduks rahulik, mitte närviline, tuli virvendus lahendada kaks korda — üks kord struktureeritud väljade jaoks, teine kord markdown''i jaoks — ja teine lahendus oli renderdaja, mis meil juba olemas oli.

Inseneeria
Front-end
Voogedastus
GeekBye väljalasked
Kuidas voogedastada reaalajas raportit ilma virvenduseta

Enne seda väljalaset tähendas GeekBye koosoleku lõpetamine spinneri vahtimist. Rakendus saatis kogu su transkriptsiooni analüüsiks ära, ootas ära terve kokkuvõtte — skoori, põhipunktid, tegevused, kõik — ja kallas selle siis korraga ekraanile. Toimis, aga see tundus aeglane, sest sa vahtisid tühjust, samal ajal kui see töötas.

GeekBye v1.6.13–v1.6.15 muutis selle raportiks, mis voogedastub reaalajas, väli väli haaval, sedamööda kuidas seda genereeritakse. Huvitav osa pole voogedastus ise — see on kõik see, mida me pidime tegema, et voogedastus ei näeks välja närviline. Rahulik voogedastus ja tõmblev voogedastus on sama funktsioon väga erineva teostusega.

Virvendus, esimene osa: ära lase igal tükil Reacti raputada

Kokkuvõte pole üks pläru — see on struktureeritud väljad (üldskoor, põhipunktid, tegevused ja nii edasi), mille backend saadab ükshaaval server-sent events'i kaudu. Naiivne viis seda renderdada on uuendada Reacti olekut iga saabuva sündmuse peale.

Tee nii ja saad virvenduse. Iga saabuv väli käivitab oma ümberrenderduse; komponendid, mis näitasid "tühja", monteeruvad, siis ühenduvad lahti, siis monteeruvad uuesti "täidetuna"; paigutus tõmbleb iga paketi peale. Raport paneb end kokku su silme all kõige halvemal võimalikul viisil — nähtavalt, närviliselt.

Lahendus on kaheosaline distsipliin. Esiteks, kogu saabuvad väljad ref'i — muudetavasse hoidjasse, mis ei käivita renderdusi — ja avalda Reacti olekusse üks kord tüki kohta värske koopiaga, nii et puu uueneb sihilikult, mitte iga mikrosündmuse peale. Teiseks, renderda kogu aeg üks stabiilne komponendipuu, olgu voogedastades või valmis, koos reasiseste kohatäidetega väljadele, mis pole veel saabunud:

// accumulate in a ref, publish once per chunk
partialRef.current = { ...partialRef.current, [field]: value }
setPartial({ ...partialRef.current })

// one tree, never swapped; missing fields show a placeholder in place
const report = isStreaming ? partial : saved
<Score>{report.overallScore ?? '…'}</Score>

Komponent, mis näitab skoori, ei ühendu kunagi lahti — see lihtsalt näitab , kuni number kohale jõuab, ja siis numbrit. Miski ei tõmble. Ja täielikult kokku pandud objekt salvestatakse lõpus ikkagi kohalikku andmebaasi, nii et voogedastuse liides ja püsiv salvestus eksisteerivad koos ilma omavahel võitlemata.

Virvendus, teine osa: renderdaja, mis meil juba olemas oli

Teine virvendus on peenem ja elab markdown''i endas. Raport renderdab rikkalikku markdown''i — pealkirju, rasvast kirja, loendeid, koodiplokke. Aga markdown, mis saabub voo keskel, on igal antud hetkel poolik. Loend seni ühe punktiga. Koodipiire, mis on avatud, aga mitte suletud. Rasva marker, millel pole veel paarilist.

Tavaline markdown''i renderdaja parsib terve sõne iga tokeni peale uuesti ning see poolik olek parsitakse iga kord millekski erinevaks — nii loend virvendab, koodiplokk vilgub avatud ja suletud, paigutus hüppab, kui tokenid valmivad. See on sama närviline kokkupanek nagu enne, üks kiht allpool.

Lahendus oli peaaegu piinlikult käepärast: me juba kasutasime voogedastusteadlikku markdown''i renderdajat reaalajas AI-vestluse jaoks. Renderdaja, mis on ehitatud taluma mittetäielikke tokeneid — renderdama poolikut markdown''i stabiilselt ja seda alles siis paika panema, kui tokenid valmivad — selle asemel et iga kord nullist uuesti parsida. Raport pidi lihtsalt sama renderdajat kasutama. Me olime täpselt selle probleemi vestluse jaoks kuid varem lahendanud; raporti "lahendus" oli mõista, et meil oli tööriist juba olemas, ja suunata see teisele pinnale. Taaskasutus võitis ümberehituse.

Boonus: vormindatud kopeerimine on lõikelaua vormingu probleem

Kui raport hakkas hea välja nägema, tahtsid inimesed seda kleepida — dokumenti, e-kirja — ja säilitada vorminduse ning ekraanipildid. Instinkt on serialiseerida raport markdown''i sõneks ja loota, et sihtkoht renderdab selle. Tavaliselt ei renderda.

Tõeline vastus on see, et lõikelaud hoiab mitut esitust korraga. Nii kirjutame me kaks: HTML-versiooni vorminduse säilitades ja ekraanipiltidega reasiseste piltidena manustatuna ning lihttekstilise varuvariandi sihtkohtadele, mis HTML-i ei võta. Kleebi rikkalikku redaktorisse ja saad vormindatud raporti piltidega; kleebi lihtteksti kasti ja saad puhta teksti. "Vormindatud kopeerimine" polnud kunagi serialiseerimise probleem — see oli õige-lõikelaua-vormingu-valimise probleem.

Sama väljalase andis raportile ka vestlusstiilis Me / Them sildid, kaks kõnelejat vastaskülgedel joondatud, nii et transkriptsioon loeb nagu vestlus, mis see oligi, ning liigutas su enda ekraanipildid nende omale poolele, et sobitada. (Üks selle akna väljalase, v1.6.14, oli puhas ümberehitus — sellel pole lugu, ja aus on seda öelda.)

Kolm asja, mida voogedastuse liides meile õpetas

  1. Puhverda voogedastatud väljad, avalda üks kord tüki kohta. Kui lased igal server-sent event''il oma olekuuuendust juhtida, siis see ongi virvendus. Ref-akumulaator pluss üks avaldus tüki kohta, puusse, mis kunagi ei ühendu lahti, muudab närvilise kokkupaneku rahulikuks täitumiseks.
  2. Kõik, mis voogedastub, vajab voogedastusteadlikku renderdajat. Renderdaja, mis parsib terve sõne iga tokeni peale uuesti, virvendab pooliku markdown''i peal. Kasuta sellist, mis on ehitatud mittetäieliku sisendi jaoks — ja kui sul on juba üks teise pinna jaoks olemas, taaskasuta seda enne, kui ehitad teise.
  3. Vormindatud kopeerimine on lõikelaua vormingutest, mitte serialiseerimisest. Kirjuta text/html manustatud piltidega ja text/plain varuvariant. Lõikelaud loodi mõlemat kandma; kasuta seda.

See on viies peatükk usaldusväärsuse-ja-viimistluse loos, millest saab GeekBye v2. Eelmise peatüki leiad earbudside vea juurest (v1.6.12); selle kohta, kuidas sama server-sent-events''i idee hiljem sai terveks varutranspordiks, reaalajas transkriptsioon, kui tulemüür blokeerib WebSocketid (v2.0.8); ja kogu kaare kohta, tarkvara täiuseni skeepimise anatoomia.

Seotud artiklid

Katkenud ühendus ei tohiks kogu rakendust maha võtta — aga meie oma tegi seda
Steven
Steven5 min lugemist

Katkenud ühendus ei tohiks kogu rakendust maha võtta — aga meie oma tegi seda

Kui meie backend kadus keset koosolekut võrgust, ei pannud see lihtsalt transkriptsiooni pausile — see pani kogu rakenduse kokku jooksma. Põhjuseks oli üksainus käsitlemata sündmus ja parandus oli kümme rida. See on väljalasete kobar, mis pani GeekBye sisselogituna ja ühendatuna püsima läbi asjade, mis teda varem tapsid.

Inseneeria
Töökindlus
Electron
Tarkvara täiuslikuna tarnimise anatoomia: kuidas koodiülevaatus tabas selle, mida testid ei suutnud
Steven
Steven5 min lugemist

Tarkvara täiuslikuna tarnimise anatoomia: kuidas koodiülevaatus tabas selle, mida testid ei suutnud

Kogu GeekBye v2 sarja vältel kordub üks ja seesama: parandus läbib arendaja masinas iga testi ning siis tõestab koodiülevaatus, et peaaegu kõigi teiste jaoks oleks see läbi kukkunud. See on üheksa väljalaske taga olev töövoog — ülevaatuse värav, esmalt-parandus tabamised ja testi-enne-tarnimist distsipliin, mis muudab "minu masinas töötab" fraasiks "see töötab".

Inseneeria
Protsess
Koodiülevaatus
Üks CSS-i muutuja, viis ülevaatusringi ja Swifti tööriistakett, mis valetas
Steven
Steven6 min lugemist

Üks CSS-i muutuja, viis ülevaatusringi ja Swifti tööriistakett, mis valetas

GeekBye v2.0.7 muutis kogu overlay reguleeritavalt läbipaistvaks — mis kõlab nagu üherealine CSS-i muudatus ja seda kindlasti ei olnud. Tegelik lugu on selles, mida koodiülevaatus tabas: kaks pinda, mis keeldusid tuhmumast, salvestusriba, mis nägi sama läbipaistvuse juures vale välja, ja kompileeritud binaar, mis kõikus 672 baiti edasi-tagasi, sest meie enda dokumentatsioon ütles ülevaatajale vale Swifti versiooni.

Inseneeria
Disain
Ehitus