Gå til hovedindhold

Da en ja-nej-besked fik sit eget nervesystem

Indsendt af Lennart den

Jeg ville have en enkel redaktionel handling: en videnshistorie skal ligge klar om formiddagen, jeg skal kunne svare ja på telefonen, og så skal den ud på Folkets uden at min Mac eller en terminal behøver stå åben.

Det lyder som en notifikation. Det er det ikke. Det er et lille distribueret system.

Spørgsmålet er en begivenhed

Den lokale redaktion sender ikke en mail, der skal læses af et menneske. Den skriver en forespørgsel til Janus med en reference til den konkrete historie. Janus viser den på telefonen. Når jeg stryger til ja eller nej, skriver Janus et svar som en begivenhed.

Det vigtige er, at svaret ikke sendes direkte til en proces, der tilfældigvis kører lige nu. Det bliver liggende i en stream. En subscriber på den lokale maskine følger streamen og skriver svaret videre til sin egen xs-store. Hvis Mac’en genstarter, starter subscriberen igen og fortsætter fra den varige state.

To feeds, to jobs

Janus’ webside har sit eget feed. Det er Datastar over SSE og sender HTML-patches til browseren. Det er det rigtige feed til en brugerflade, men et dårligt interface til en worker.

Derfor fik worker’en sit eget endpoint. Det sender newline-delimited JSON: én maskinlæsbar event pr. linje. Browseren og worker’en deler dermed ikke protokol bare fordi de deler server.

Det lyder som en lille detalje, men den slags skel gør systemer begribelige. UI-feedet må gerne tale i patches. Worker-feedet skal tale i facts.

Streamen skal ende i en handling

Når svaret lander lokalt, reagerer xs-processen på eventet. Den slår den oprindelige forespørgsel op, kontrollerer reference og fingerprint og kører derefter preview før publicering. Først efter den eksterne skrivning bliver forløbet markeret som publiceret.

Long-polling findes stadig som sikkerhedsnet, hvis forbindelsen til streamen falder. Men normalvejen er nu reaktiv: et svar på telefonen bliver til et event, et event bliver til en handling.

Det er forskellen på at spørge en server igen og igen, om der er sket noget, og at abonnere på, at noget sker.

Den lille fejl, der afslørede systemet

Under testen virkede Janus-feedet, men intet kom ind i den lokale store. Fejlen var ikke dramatisk. launchd kendte ikke Homebrew-stien til xs. Subscriberen modtog svaret, men kunne ikke skrive det videre.

Det er præcis den slags fejl, event sourcing gør synlig. Hvert led har sit eget spor: spørgsmålet, svaret, den lokale afledning og den endelige publicering. Man kan se, hvor kæden knækker, i stedet for at gætte på, om en knap blev trykket.

Det er også derfor, state skal ligge uden for kodecheckoutet. På serveren ligger Janus’ kode og event-store i cross.streams vedvarende state/. På Mac’en ligger xs-storet i Application Support. Kode kan deployes igen. Historikken skal blive.

En ja-nej-besked er dermed blevet et lille nervesystem: en impuls fra telefonen, en stream gennem systemet og en kontrolleret handling i den redaktionelle ende.