Kartan · Del två · Maskinen · Kapitel 17 av 23
Nattkörningen
Klockan halv elva går en klocka igång. Kurser kontrolleras på nytt mot beslut som redan fattats, filer skrivs, och körningen lämnar via en av två utgångar: en tyst signal till en yttre observatör, eller ett rop till ägarens telefon. Ungefär 7 minuter.
Servrar har ingen människa som sitter vid dem. För att få något att hända vid samma tid varje dag skriver du två små filer åt operativsystemets schemaläggare. Den ena är en timer: den säger när. Den andra är en tjänst (service): den säger vad. Schemaläggaren här är den som är inbyggd i modern Linux, kallad systemd, och filerna kallas enheter (units).11deploy/vss.timer och deploy/vss.service.
När
Varje dag klockan 22:30, sedan de sista europeiska och amerikanska börserna har stängt och kurserna har lagt sig. Om maskinen var avstängd klockan 22:30 kör timern jobbet så snart maskinen är tillbaka, i stället för att hoppa över dagen.22OnCalendar=*-*-* 22:30:00; Persistent=true.
Vad
Nattkörningen läser in ägarens fil, hämtar dagens kurser, räknar fram den fasta uppsättningen nyckeltal, jämför varje kurs med de nivåer som redan är skrivna för det bolaget, skriver rapporten, skriver en rad per bolag i körningsdatabasen och genererar sedan översiktssidan. Sidgenereringen körs sist och är ordnad så att körningen ändå är en framgång om den misslyckas: rapporten och databasraden kommer först, och ett misslyckande att rita sidan loggas som en varning, inte som ett misslyckande för natten.33Översiktssidan 'åker med i samma enhet efter att rapporten och databasraden skrivits och kan inte bryta körningen'.
Vad den inte kan röra
Körningen är inhägnad av operativsystemet, inte bara av sin egen kod. Den ser hela systemet som skrivskyddat. Den ser ägarens hemkatalog som skrivskyddad. De enda två mappar den får skriva i är datamappen och rapportmappen. Den kan inte få några nya behörigheter när den väl startat, och den avbryts om den körs längre än femton minuter.44ProtectSystem=strict; ProtectHome=read-only; ReadWritePaths= bara data- och rapportmapparna; NoNewPrivileges=true; TimeoutStartSec=15min. Det här är den första väggen från kapitel 14, dragen av en annan hand: även om koden hade ett fel som försökte skriva ett beslut i ägarens fil skulle operativsystemet vägra.
De två utgångarna
En körning slutar på ett av två sätt, och varje sätt ger ett olika ljud.
- Framgång. Direkt efter att körningen slutförts skickar ett separat enradsskript en enda, tom förfrågan till en yttre övervakningstjänst. Den bär inget bolagsnamn, ingen kurs, ingen rapport, inget maskinnamn: en förfrågan till en ogenomskinlig adress, som betyder "körningen skedde". Om själva den förfrågan misslyckas räknas körningen ändå som en framgång; en misslyckad signal får inte förvandla en bra natt till en dålig.55ExecStartPost=- pingskriptet; bindestrecket i början betyder att dess misslyckande inte får enheten att misslyckas. Skriptets egen kommentar: 'VAD SOM LÄMNAR MASKINEN: en HTTP GET till ett ogenomskinligt UUID. Ingen ticker, ingen kurs, ingen rapport, inget värdnamn, ingen kropp.'
- Misslyckande. Om körningen avslutas med ett fel eller avbryts för att den körts för länge startar schemaläggaren en andra enhet vars enda uppgift är att meddela. Den enheten kör ett vanligt skalskript, avsiktligt inte programmets eget språk, eftersom det som gick sönder kan vara programmets egen miljö. Skriptet skickar ett meddelande till ägarens telefon som säger vilken enhet som stannade och vad det betyder, med de sista åtta raderna ur loggen.66OnFailure=vss-failure@%n.service; deploy/vss-notify-failure.sh. Hjärtslagsmodulen: 'Det är avsiktligt en vanlig curl i ett skalskript och INTE det här paketet: felet som rapporteras kan mycket väl VARA det här paketet.'
Lägg märke till asymmetrin. Framgång är tyst på telefonen. Ägaren vill inte ha ett meddelande varje natt som säger att ingenting hände; ett meddelande som alltid kommer är ett meddelande som slutar läsas. Framgång ger sitt ljud någon annanstans, till en observatör vars uppgift är att märka om ljudet uteblir. Det är kapitel 18.
Veckokörningen
Screenern körs enligt samma mönster, på lördagsmorgnar klockan 08:00, på fredagens avstämda kurser, med en fyratimmarsgräns och ett strängare stängsel: mappen med ägarens fil är över huvud taget inte skrivbar för den. Den enda raden är beslutet "den schemalagda screeningen tar aldrig in ett bolag" skrivet på schemaläggarens språk.77deploy/vss-screen.timer: Sat 08:00; tjänstens skrivskyddade konfigurationsmapp, i projektbeskrivningen kallad 'E93 på en rad'. Uppmätt 2026-08-31: omkring 38 minuter, 3 495 förfrågningar om grunddata, noll strypningar. En tredje timer, klockan 09:30 varje dag, tillhör dödmansgreppet.
Enheterna, med ord
vss.timer startar vss.service klockan 22:30 varje dag och tar igen om den missats. Tjänsten är engångs (one-shot), kör nattkommandot i en sandlåda som bara är skrivbar i data- och rapportmapparna, pingar den yttre observatören vid framgång och startar vss-failure@vss.service vid misslyckande. vss-screen.timer startar vss-screen.service på lördagar klockan 08:00 med konfigurationsmappen skrivskyddad. vss-checkin.timer startar vss-checkin.service klockan 09:30 varje dag. vss-failure@.service är en mall: namnet på den misslyckade enheten fylls i och skickas till notifieringsskriptet, som alltid avslutas med framgång, eftersom "en felnotifierare som kan misslyckas är en andra sak att övervaka".
Källor för det här kapitlet
- Schemaläggarens enheter och skript — läst ur det här repot: deploy/vss.timer, deploy/vss.service, deploy/vss-screen.timer, deploy/vss-checkin.timer, deploy/vss-failure@.service, deploy/vss-ping-healthcheck.sh, deploy/vss-notify-failure.sh, deploy/README.md
Den långsamma vägen, gjord uthärdlig. Byggd 2026-09-13 ur repot som det såg ut den dagen. BOLAG A och BOLAG B är påhittade; inget bolag, ingen kurs och inget innehav förekommer på den här sajten. Inte finansiell rådgivning: en privatinvesterares metod, delad som den är.