Steven
Steven5 min lasīšana

Kā straumēt tiešraides atskaiti bez mirgoņas

Kad tava sanāksme beidzas, GeekBye kopsavilkums tagad aizpildās tiešraidē, nevis liek tev blenzt uz griežamo ikonu. Lai straumēšanas saskarne justos mierīga, nevis raustīga, mirgoņa bija jāatrisina divreiz — vienreiz strukturētiem laukiem, otrreiz markdown formātam — un otrais risinājums bija renderētājs, kas mums jau piederēja.

Izstrāde
Priekšpuse
Straumēšana
GeekBye laidieni
Kā straumēt tiešraides atskaiti bez mirgoņas

Pirms šī laidiena GeekBye sanāksmes beigšana nozīmēja blenšanu uz griežamo ikonu. Lietotne nosūtīja visu tavu transkriptu analīzei, gaidīja visu kopsavilkumu — vērtējumu, galvenos punktus, uzdevumus, visu pilnībā — un tad izgāza to ekrānā uzreiz. Funkcionāli, bet tas šķita lēni, jo tu blenzi uz tukšumu, kamēr tas strādāja.

GeekBye v1.6.13–v1.6.15 pārvērta to par atskaiti, kas ieplūst tiešraidē, lauku pa laukam, tiklīdz tā tiek ģenerēta. Interesantākā daļa nav pati straumēšana — tas ir viss, kas mums bija jādara, lai straumēšana neizskatītos raustīga. Mierīga straumēšana un raustīga straumēšana ir viena un tā pati funkcija ar ļoti atšķirīgu izpildījumu.

Mirgoņa, pirmā daļa: neļauj katram gabalam kratīt React

Kopsavilkums nav viens bloks — tie ir strukturēti lauki (kopējais vērtējums, galvenie punkti, uzdevumi un tā tālāk), ko aizmugure izdod pa vienam pa server-sent events. Naivais veids, kā to renderēt, ir atjaunināt React stāvokli katrā notikumā, tiklīdz tas pienāk.

Dari tā, un tu dabū mirgoņu. Katra pienākošā lauka atnākšana izraisa savu atkārtotu renderēšanu; komponenti, kas rādīja "tukšu", pievienojas, tad atvienojas, tad pievienojas atkal kā "ielādēti"; izkārtojums saraustās uz katras paketes. Atskaite pati salikās tavu acu priekšā pašā sliktākajā iespējamā veidā — redzami, nervozi.

Risinājums ir divdaļīga disciplīna. Pirmkārt, uzkrāj pienākošos laukus ref — maināmā turētājā, kas neizraisa renderēšanu — un publicē React stāvoklī vienreiz uz gabalu ar svaigu kopiju, lai koks atjauninās apzināti, nevis uz katra mikronotikuma. Otrkārt, renderē vienu stabilu komponentu koku visu laiku, vienalga vai straumējot vai pabeidzot, ar iekļautiem vietturiem laukiem, kas vēl nav pienākuši:

// 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>

Komponents, kas rāda vērtējumu, nekad neatvienojas — tas vienkārši rāda , līdz skaitlis nokrīt vietā, tad skaitli. Nekas nesaraustās. Un pilnībā saliktais objekts beigās joprojām tiek kešots vietējā datubāzē, tāpēc straumēšanas saskarne un noturīgā glabāšana pastāv līdzās, necīnoties.

Mirgoņa, otrā daļa: renderētājs, kas mums jau piederēja

Otrā mirgoņa ir smalkāka un mīt pašā markdown. Atskaite renderē bagātīgu markdown — virsrakstus, treknrakstu, sarakstus, koda blokus. Bet markdown, kas pienāk straumes vidū, jebkurā konkrētajā mirklī ir līdz galam nepabeigts. Saraksts ar līdz šim vienu aizzīmi. Koda ietvars, kas ir atvērts, bet nav aizvērts. Treknraksta marķieris bez pāra.

Parasts markdown renderētājs atkārtoti parsē visu virkni uz katra tokena, un šis nepabeigtais stāvoklis katru reizi parsējas par kaut ko citu — tāpēc saraksts mirgo, koda bloks pazibina atvēršanu un aizvēršanu, izkārtojums lēkā, tokeniem pabeidzoties. Tā ir tā pati nervozā montāža kā iepriekš, vienu slāni dziļāk.

Risinājums bija gandrīz apkaunojoši pieejams: mēs jau izmantojām straumēšanu apzinošu markdown renderētāju tiešraides AI tērzēšanai. Renderētāju, kas būvēts, lai panestu nepabeigtus tokenus — lai renderētu līdz galam nepabeigtu markdown stabili un nostabilizētu to tikai tad, kad tokeni pabeidzas — nevis parsētu no jauna katru reizi. Atskaitei vienkārši vajadzēja izmantot to pašu. Mēs bijām atrisinājuši tieši šo pašu problēmu tērzēšanai mēnešus iepriekš; "risinājums" atskaitei bija atzīt, ka mums jau ir rīks, un pavērst to uz otru virsmu. Atkārtota izmantošana uzvarēja pārbūvi.

Bonuss: formatēta kopēšana ir starpliktuves formāta problēma

Kad atskaite izskatījās labi, cilvēki gribēja to ielīmēt — dokumentā, e-pastā — un saglabāt formatējumu un ekrānuzņēmumus. Instinkts ir serializēt atskaiti par markdown virkni un cerēt, ka galamērķis to renderēs. Parasti tā nenotiek.

Īstā atbilde ir tāda, ka starpliktuve tur vairākas reprezentācijas vienlaikus. Tāpēc mēs rakstām divas: HTML versiju ar neskartu formatējumu un ekrānuzņēmumiem, kas iegulti kā iekļauti attēli, un vienkārša teksta rezerves variantu galamērķiem, kas nepieņem HTML. Ielīmē bagātīgā redaktorā un tu dabū formatētu atskaiti ar attēliem; ielīmē vienkārša teksta lodziņā un tu dabū tīru tekstu. "Formatēta kopēšana" nekad nebija serializācijas problēma — tā bija izvēlies-pareizo-starpliktuves-formātu problēma.

Tas pats laidiens deva atskaitei arī tērzēšanas stila Me / Them etiķetes ar diviem runātājiem, kas izlīdzināti pretējās pusēs, tāpēc transkripts lasās kā saruna, kas tas bija, un pārvietoja tavus paša ekrānuzņēmumus uz to pašu pusi, lai saskanētu. (Viens laidiens šajā logā, v1.6.14, bija tīra pārbūve — nekāda stāsta tur nav, un ir godīgi to pateikt.)

Trīs lietas, ko straumēšanas saskarne mums iemācīja

  1. Buferē straumētos laukus, publicē vienreiz uz gabalu. Ļaut katram server-sent event vadīt savu stāvokļa atjauninājumu ir mirgoņa. Ref uzkrājējs plus viena publikācija uz gabalu, kokā, kas nekad neatvienojas, pārvērš nervozo montāžu par mierīgu aizpildīšanos.
  2. Jebkam, kas straumē, vajag straumēšanu apzinošu renderētāju. Renderētājs, kas atkārtoti parsē visu virkni uz katra tokena, mirgos uz līdz galam nepabeigta markdown. Izmanto tādu, kas būvēts nepilnīgai ievadei — un ja tev jau ir tāds citai virsmai, izmanto to atkārtoti, pirms būvē otru.
  3. Formatēta kopēšana ir par starpliktuves formātiem, nevis serializāciju. Raksti text/html ar iegultiem attēliem un text/plain rezerves variantu. Starpliktuve tika izstrādāta, lai nestu abus; izmanto to.

Šī ir piektā nodaļa uzticamības-un-pulēšanas stāstā, kas kļūst par GeekBye v2. Par iepriekšējo nodaļu skati earbuds kļūdu (v1.6.12); par to, kur tā pati server-sent-events ideja vēlāk kļuva par veselu rezerves transportu, tiešraides transkripcija, kad ugunsmūris bloķē WebSocket (v2.0.8); un par visu loku, programmatūras nogādāšanas līdz pilnībai anatomija.

Saistītie raksti

Viens CSS mainīgais, piecas pārskatīšanas kārtas un Swift rīkkopa, kas meloja
Steven
Steven6 min lasīšana

Viens CSS mainīgais, piecas pārskatīšanas kārtas un Swift rīkkopa, kas meloja

GeekBye v2.0.7 padarīja visu pārklājumu regulējami caurspīdīgu — kas izklausās pēc vienas rindas CSS izmaiņas, bet nekādā ziņā tāda nebija. Īstais stāsts ir par to, ko pamanīja koda pārskatīšana: divas virsmas, kas atteicās izbālēt, ierakstīšanas josla, kas pie tās pašas necaurspīdības izskatījās nepareizi, un kompilēts binārais fails, kas mainīja 672 baitus turp un atpakaļ, jo mūsu pašu dokumentācija pārskatītājam pateica nepareizo Swift versiju.

Izstrāde
Dizains
Būvēšana
Mierīga programmatūra: kā nogalināt mirgojošu slēdzi un iemācīt tērzēšanai pateikt, kādā režīmā tā ir
Steven
Steven5 min lasīšana

Mierīga programmatūra: kā nogalināt mirgojošu slēdzi un iemācīt tērzēšanai pateikt, kādā režīmā tā ir

Divi nelieli GeekBye laidieni bez lielām funkcijām — tikai iestatījumu slēdzis, kas beidza mirgot, un tērzēšanas asistents, kas beidzot pasaka, vai atbildēja sapulces režīmā vai kodēšanas režīmā. Lūk, cik patiesībā maksā "mierīga programmatūra", pa vienai detaļai.

Produkts
Dizains
Izstrāde
Pārtraukts savienojums nedrīkstētu avarēt visu lietotni — bet mūsējo tas avarēja
Steven
Steven6 min lasīšana

Pārtraukts savienojums nedrīkstētu avarēt visu lietotni — bet mūsējo tas avarēja

Kad mūsu backend pazuda tiešsaistes sapulces vidū, tas ne tikai apturēja transkripciju — tas avarēja visu lietotni. Cēlonis bija viens neapstrādāts notikums, un labojums bija desmit rindas. Šī ir izlaidumu kopa, kas panāca, ka GeekBye paliek pieteicies un savienots cauri lietām, kas to agrāk nogalināja.

Izstrāde
Uzticamība
Electron