Tilannekuva 17.8.2026 · päivä ajettiin 15.8.
Sääksi 10+1 Laps — arkkitehtuuri
Kaksi kaaviota: mitä tapahtuu pyynnön aikana, ja miten koodi päätyy ajoon. Edellinen versio tästä dokumentista oli neljä päivää ennen tapahtumaa; tämä kuvaa sen mikä on nyt tuotannossa — live-päivän koneisto ja kaikki mitä sen jälkeen rakennettiin: arkisto, replay, kuvavirta, kuskien omat nauhoitukset, timelapse ja 2027-äänestys. Kaikki pyörii Cloudflaren ilmaistasolla.
Ajonaikainen rakenne
Koko järjestelmä on staattinen sivusto ja yksi Worker. Kiinnostavat kohdat ovat ne, mitä selain ei voi tehdä itse — ja ne, mitä Worker ei ehdi tehdä, koska ilmaistaso antaa pyynnölle noin 10 ms CPU-aikaa ja noin 50 alipyyntöä.
customMetadata-kenttiin: kahdensadan äänen tulostaulu on yksi
list()-kutsu, ei kahtasataa hakua — alipyyntöraja teki siitä
arkkitehtuuripäätöksen.
Raskas työ ei ole Workerissa
Kuskin GPX parsitaan selaimessa — kilometrit, nousut ja kierrokset lasketaan siellä ja Worker vain tarkistaa, että luvut täsmäävät piirretyn viivan kanssa. Replay-data, timelapse ja musiikki lasketaan kokonaan etukäteen ja julkaistaan staattisina tiedostoina.
Avoimet lomakkeet, hyväksyntä portilla
Kuka tahansa voi lähettää kuvia tai oman jälkensä ilman tiliä. Turnstile torjuu botit
(jokaisella lomakkeella oma action), ja sisältö tulee näkyviin vasta kun
merkkiobjekti kirjoitetaan R2:een. Kuka tahansa saa piilottaa kuvan; vain ylläpito palauttaa.
Hätäkatkaisin
Yksi kytkin sulkee kaikki kirjoituspolut ja piilottaa sisällön poistamatta mitään. Kuskien sijainnit jatkuivat silti, koska ne tulivat Stravasta eikä niitä voinut lähettää tänne. Vapautus on yksi painallus.
Julkaisu ja jälkikäsittely
Kaksi wrangler-komentoa samasta repositoriosta, ja niiden rinnalla Python-putki, joka jalostaa arkiston sivuiksi.
pipeline/
lukee arkiston ja kuvat, rakentaa replay-datan, rekonstruoi aikaleimattomien jälkien kellot
vierellä ajaneen jäljestä, leipoo timelapsen musiikkeineen ja piirtää jokaiselle jaettavalle
osoitteelle oman kortin — ja tulokset julkaistaan takaisin samalle staattiselle sivustolle.
GitHubissa on lähdekoodi, mutta julkaisu tapahtuu yhä yhdeltä koneelta.
| Osoite | Mitä se on | Data |
|---|---|---|
| saaksi.bike | Tapahtumasivu: kuvavirta, oma jälki -lomake, aita-video | Worker: /photos, /recordings |
| /live | Live-kartta — tapahtumapäivän näkymä | live.json, 10 s reunacache |
| /replay | Koko päivä uudelleen: 5 kuskia, 39 kuvaa, jaettavat hetkilinkit | staattinen data.json, kuvat livenä |
| /aita | Timelapse: sama portti joka kierroksella, kello ja km kuvassa | staattinen mp4, ääni syntetisoitu |
| /2027 | Avoin äänestys ensi vuoden päivästä — piilotettu, linkittämätön | yksi R2-objekti per ääni |
| /pakkauslista | Katselmoitu pakkauslista — mikä toimi 203 km:n päivänä | staattinen, rastit selaimessa |
| …workers.dev/admin | Hyväksynnät, aikaleimakorjaukset, hätäkatkaisin | avainlinkki → 7 vrk keksi |
Jokaisella jaettavalla osoitteella oma kortti
Fragmentti (#kuvat) ei voi saada omaa esikatselua, koska WhatsApp näkee vain
sivun — siksi jaettavat asiat ovat oikeita polkuja. Kortit piirretään sivujen omasta datasta,
joten ne eivät voi valehdella.
Rekonstruoitu kello sanotaan ääneen
Sports Trackerin vienti on reitti ilman aikaleimoja. Kahden kuskin kello on luettu vierellä ajaneen jäljestä — lähin piste, aikaisin samanarvoinen voittaa, mahdottomat nopeudet levitetään matkalla. Merkitty dataan ja kerrottu sivulla.
Raakadata jalostetun rinnalla
Arkisto tallentaa aina Stravan koskemattoman vastauksen GPX:n viereen, ja kuskin lähettämä alkuperäinen tiedosto säilyy missä tahansa muodossa se tuli. Rekonstruktio on arvostelma, joka pitää voida tehdä uudestaan.
Mikä muuttui 11.8. jälkeen
Edellisen tilannekuvan aukkolista, rivi riviltä.
-
„Arkistointi puuttuu kokonaan" — suljettu ennen lauantaita.
Cron kirjoitti jokaisen kuskin jäljen R2:een koko päivän, tapahtumapäivänä kahden minuutin
välein, ja tallensi vain kun pisteitä oli — siksi viimeinen hyvä tiedosto selvisi hetkestä,
jolloin Strava käänsi beaconin
saved-tilaan. Replay on olemassa, koska tämä ehti valmiiksi. - „Vain Strava tuottaa sijainnin" — ratkesi eri tavalla kuin suunniteltiin. Parsijoita muille live-palveluille ei kirjoitettu. Sen sijaan tapahtuman jälkeen kuka tahansa voi lähettää oman nauhoituksensa tiedostona: GPX aikaleimoilla parsitaan selaimessa, muut muodot arkistoidaan sellaisenaan odottamaan. Teemun kadonnut aamu, Villen Strava-jälki ja Peetun päivä tulivat kartalle tätä kautta.
- „Ingest tuntee yhden kuskin" — jäi sellaiseksi. Varareittiä ei koskaan tarvittu; Beacon kesti koko päivän.
- „Julkaisu on yhden koneen varassa" — totta yhä. Tietoinen valinta yhden viikonlopun tapahtumalle, mutta 2027:lle GitHub-kytkentä Pagesiin olisi halpa vakuutus.
Ansat jotka on kohdattu
Jokainen maksoi aikaa kerran. Ne eivät näy kaavioissa mutta kuuluvat kuvaan.
~50 alipyyntöä per pyyntö
Äänestyksen tulostaulu objektirunkoina olisi ylittänyt rajan heti. Sisältö
customMetadata-kenttiin ja yksi listaus — sama temppu kuvavirrassa ja
nauhoituslistassa.
R2-metadata kulkee HTTP-otsakkeissa
Ääkköset ja rivinvaihdot kaatavat kirjoituksen, ellei kaikkea prosenttikoodaa. Ja metadataa ei voi päivittää ilman että objektin runko kirjoitetaan uudelleen — aikaleiman korjaus on siirto uuteen avaimeen, koska aika on avaimen etuliite.
--branch main, repon juuresta
Ilman haaraa julkaisu menee preview-osoitteeseen eikä mikään kerro virheestä;
site/-hakemistosta ajettuna wrangler etsii polkua site/site.
Reunat päivittyvät eri tahtiin vielä minuutin pari julkaisun jälkeen.
Pysähtynyt GPS ja „lähin piste"
Kun referenssikuski seisoo, sata pistettä on samassa paikassa ja „lähin" on arpapeli — väärä valinta siirsi kelloa 39 minuuttia ja puristi kymmenen kilometriä kolmeen minuuttiin. Aikaisin samanarvoinen voittaa: saapuminen on hetki jolloin paikalle ensin tultiin.
Neljän tunnin oletuscache
Pages tarjoaa staattista sisältöä neljä tuntia, mikä tapahtuma-aamuna tarkoittaisi
eilistä JavaScriptiä. _headers pakottaa HTML:n ja skriptien revalidoinnin
joka latauksella; 304 maksaa kierroksen, ei latausta.
CSS-spesifisyys söi napit
.button.primary voitti lomakekohtaiset säännöt ja kaksi lähetysnappia oli
kermanvärisiä kermanvärisellä pohjalla. Korjaus oli pinnan mukainen scope, ei
!important.