BibliotekSammanhängande läsvyEPUB
Del II — Den levande modellen · Kapitel 6

Händelser, fullständighet och färskhet

Klockan 09.09 visar Nordic fyra gröna komponenter. Ett DocumentGenerated har nyligen observerats och eventflödet är färskt. Ändå saknas fem av 142 verifierade mottagningskvitton.

Det är inget motsägelsefullt i detta. Tre olika frågor har besvarats:

  1. Lever komponenterna? Ja, enligt färska health-observationer.
  2. Har flödet nyligen producerat event? Ja.
  3. Har alla 142 dokument nått rätt slutstatus? Det vet Matrix ännu inte.

Ett kontrollager som blandar dessa frågor kan vara tekniskt realtidsuppdaterat och samtidigt operativt fel.

1. Eventet är ett påstående om en förekomst

Ett event representerar att något inträffade: ett processteg startade, ett dokument genererades, en deployment applicerades eller ett webhookkvitto observerades. Eventet är inte själva förekomsten. Det är en post skapad av en producent med den precision, identitet och täckning som producenten förmår.

Matrix eventkontrakt kräver i nuläget:

  • id,
  • en typ ur eventvokabulären,
  • occurredAt med explicit tidszon,
  • minst en sourceRef.

subjectNodeId, relatedNodeIds, metadata och bundlets generatedAt är valfria (MATRIX-EVENT-CONTRACT). Kontraktet ger därmed en god miniminivå för tid och källpekare, men varje event kan inte antas vara korrelerbart till ett stabilt grafsubjekt.

CloudEvents använder source + id som unik identitet för en distinkt händelseförekomst och låter en omsänd dubblett behålla samma identitet (cloudevents10). Matrix har producerId på bundle och id på event. Parets likhet med CloudEvents är en möjlig exportprofil, inte ännu ett uttalat likhetstecken mellan modellerna.

2. Fem oberoende kvalitetsfrågor

Innan ett event används som kunskap bör Matrix pröva minst fem frågor:

Dimension Fråga Fel som kan döljas
Giltighet Följer posten schema och vokabulär? trasig tid, okänd typ
Identitet Är förekomsten unik eller en omsändning? dubbelräkning
Korrelation Vet vi vilket subjekt, flöde och scope den tillhör? rätt event på fel objekt
Färskhet Har relevanta flöden observerats inom avtalad tid? död producent
Fullständighet Har den mängd som beslutet kräver observerats? tyst bortfall

En grön rad i en dimension får inte färga de andra gröna.

3. Färskhet är ett flödeskontrakt

Matrix stalenessgrind arbetar per (producerId, eventType). Varje registrerad producent måste ha en policy. Ett flöde kan antingen:

  • vara levande med en positiv maxAgeDays,
  • vara avsiktligt dormant genom acceptedStale och en riktig orsak,
  • eller tillhöra en producent som uttryckligen inte förväntas emittera event.

Saknad policy, observerad men obokad eventtyp, ett levande flöde utan event eller ett event äldre än tillåten ålder stoppar aggregate build (MATRIX-EVENT-STALENESS). Undantag utan orsak är röda och stale bookings lyfts för borttagning.

Detta löser ett viktigt problem: en eventström kan inte dö tyst och fortsätta presenteras som aktuell. Det är också ett exempel på varför en enda global freshnessgräns är fel. I den faktiska policyn har arbetsdrivna flöden olika dagbudgetar. GeneratorFailed är avsiktligt acceptedStale, eftersom tystnad är det normala när inget misslyckas. En policy som kräver färska fel skulle kräva att systemet regelbundet producerar fel för att bli grönt (CLAIM-EVENT-005).

3.1 En artefakt är inte färskare än sitt äldsta obligatoriska underlag

Matrix har nu även en fail-closed freshnessgrind för genererade evidensartefakter. Den skiljer generatorns generatedAt från källornas validAt: att bygga om en dashboard i dag gör inte gårdagens observationer nya. Kedjans trovärdiga freshness begränsas av den äldsta obligatoriska källan. Stale, malformed och obokade källor fäller grinden; en källa utan tidsstämpel måste uttryckligen bokas i policyn. Detta skyddar Command Center mot “nytt skal runt gammal grön bild” (MATRIX-EVIDENCE-FRESHNESS, CLAIM-EVENT-007).

4. Färskt är inte fullständigt

Anta att Nordic får ett nytt kvitto för dokument 137 varje minut men aldrig får kvitton för 138–142. WebhookDelivered kan förbli färskt för alltid. Slutresultatet är ändå ofullständigt.

Matrix nuvarande stalenesspredikat väljer det senaste occurredAt per eventtyp. Det bedömer inte:

  • om alla förväntade subjekt har event,
  • om sekvensnummer har luckor,
  • om alla partitioner eller sidor lästes,
  • om antal unika event matchar en deklarerad population,
  • om varje start fått ett terminalt utfall,
  • om en viss tenant eller miljö saknas.

Det är rätt avgränsning för en liveness-/stalenessgrind, men fel verktyg för att hävda total täckning (CLAIM-EVENT-001).

5. Fullständighet kräver en nämnare

"Vi har 137 kvitton" är ett antal. "Vi har 137 av 142 förväntade unika dokument före deadline" är ett fullständighetspåstående. Nämnaren, scope och gränsen gör skillnaden (CLAIM-EVENT-002).

Vanliga fullständighetskontrakt är:

Kontrakt Exempel Bevis för lucka
Population 142 namngivna dokument ska få terminal status subjektmängdens differens
Sekvens offset 1001–1142 ska observeras saknade intervall
Livscykel varje ProcessStarted följs av terminalt event öppna instanser
Partition alla 12 källpartitioner ska passera cursor C partition-watermarks
Batch manifest med 142 poster och digest manifest kontra utfall
Sampling 10 % enligt deklarerad urvalsregel urvalsram och seed
Negativt flöde fel emitteras endast vid fel bevisad observationsförmåga, inte färska fel

Alla eventflöden behöver inte alla kontrakt. Men varje beslutsfråga behöver ett svar på "komplett relativt vad?".

6. Händelsetid och observationstid

occurredAt är tiden då producenten säger att förekomsten inträffade. Om ett kvitto skapas 09.07 men når Matrix 09.24 är det sent observerat, inte en händelse som inträffade 09.24.

OpenTelemetry Logs Data Model skiljer Timestamp, mätt vid ursprunget, från ObservedTimestamp, mätt när insamlingssystemet observerar posten (otel-logs-data-model). Samma separation behövs för att mäta:

  • transport- och insamlingsfördröjning,
  • sena event,
  • källklockans avvikelse,
  • när Matrix faktiskt kunde känna till förekomsten,
  • om en backfill felaktigt ser ut som realtid.

Matrix bundlets valfria generatedAt är inte samma sak som ett per-event observedAt eller recordedAt. Ett bundle kan byggas om långt efter att enskilda event samlades in. RESEARCH-014 prövar därför en additiv profil mot CloudEvents och OpenTelemetry innan kärnschemat ändras (CLAIM-EVENT-003).

7. Ordning och korrelation

Sortering på occurredAt ger inte automatiskt kausal ordning. Två källsystemklockor kan gå olika, och event kan transporteras olika vägar. Lamports happened-before-relation visar varför kausalitet behöver explicita meddelande- eller processrelationer, inte bara fysisk tid (lamport1978time, CLAIM-TIME-002).

En användbar eventprofil kan därför behöva:

eventIdentity: source + id
subjectIdentity
tenant + environment
occurredAt
observedAt / recordedAt
correlationId
causationId
traceId + spanId när relevant
partition + sequence/offset när källan erbjuder det
sourceRef + source revision/cursor

correlationId grupperar exempelvis alla event i batchen. causationId anger vilket event som direkt utlöste nästa. Trace context passar tekniska requestkedjor men ersätter inte alltid verksamhetskorrelation: en batch kan leva längre än en trace och passera asynkrona eller manuella gränser.

8. Dubbletter, retries och idempotens

Matrix validator räknar event-ID:n i varje bundle och vägrar dubbletter. Regeln tillkom efter att en producent använde sekundupplösning och gav två distinkta event samma ID (MATRIX-EVENT-VALIDATION). Det är en stark identitetsgrind.

Tre situationer måste ändå skiljas:

  1. Omsändning: samma förekomst skickas igen med samma ID.
  2. Retry: ett nytt försök är en ny förekomst med eget ID men samma correlation/causation-kedja.
  3. Kollision: olika förekomster får felaktigt samma ID.

Deduplicering kan hindra att samma event räknas två gånger i en viss läsmodell. Den garanterar inte att en extern side effect bara utförs en gång. Om en konsument skriver till xECM och kraschar före sitt acknowledgement kan samma leverans behandlas igen. Stabil identitet behöver därför kombineras med idempotency key, transaktionell inbox/outbox eller annan konsumentspecifik effektgrind (CLAIM-EVENT-004).

9. Watermark: när slutar vi vänta?

I ett obegränsat och oordnat flöde vet konsumenten normalt inte att alla data har anlänt. Dataflow-modellen gör avvägningen mellan korrekthet, latens och kostnad explicit (akidau2015dataflow). Streamprocessorer använder watermarks för att ange att eventtiden sannolikt avancerat förbi en gräns; senare event behandlas enligt en deklarerad latenesspolicy (flink-watermarks).

För Nordic kan policyn vara:

window: batchens start till receiptDeadline 09.10
firstResult: publicera preliminärt vid 09.10
allowedLateness: 20 minuter
stabilAccordingToPolicy: 09.30
lateHandling: korrigera additivt och märk tidigare assessment superseded
neverSilentlyDrop: sena avvisanden skapar finding även efter finalitet

En watermark är inte ett bevis på ontologisk fullständighet. Den är ett versionsbundet beslut att sluta vänta enligt känd fördröjningsmodell (CLAIM-EVENT-006). Därför bör gränssnittet säga stabil enligt policy v3, inte bara final.

10. Nordic: från 137 till känt utfall

Vid 09.10 känner Matrix till:

  • 142 förväntade dokument,
  • 142 genererade,
  • 137 verifierade kvitton,
  • 5 okända slututfall.

Två event med occurredAt omkring 09.07 registreras först 09.24. Bedömningen för deadline korrigeras då till 139 verifierade och 3 okända. Vid 09.31 kommer två retrykvitton. Vid 09.33 kommer ett belagt avvisande för dokument 142.

Observera språket:

  • 09.10: preliminärt och ofullständigt, inte failed,
  • 09.24: korrigerat med sen data, fortfarande tre okända,
  • 09.31: 141 accepterade, ett okänt, inte 142 levererade,
  • 09.33: 141 accepterade, ett avvisat, populationen har terminal status.

Komponenthälsan ändrar inget av dessa objektsutfall.

11. Täckning som operativ produktfunktion

För varje eventbaserad vy bör Matrix kunna redovisa:

expected subjects / partitions / sequence interval
observed unique events
duplicates and collisions refused
missing subjects or ranges
newest occurredAt
newest observedAt
watermark and allowed lateness
late/retracted/corrected counts
source cursor or revision
policy id and version

Om ingen nämnare finns ska vyn säga färskt flöde, okänd objektfullständighet. Detta är mer informativt än ett generellt gult eller grönt ljus.

12. Konsekvenser för Matrix självt

Samma krav gäller Coordinator och agenter. Ett färskt heartbeat visar kontakt, inte att agenten läst alla uppgifter, producerat korrekt resultat eller att alla run records nått terminal status. En kövy behöver därför separat visa:

  • heartbeat-/leasefärskhet,
  • antal förväntade och observerade run transitions,
  • öppna körningar utan terminal post,
  • dubbletter och redispatches,
  • eventfördröjning och senaste lyckade materialisering,
  • vad som aldrig instrumenterats.

Detta förbereder kapitel 11 och 15: Matrix måste mäta sin egen observationsförmåga med samma stränghet som kundsystemens.

13. Teknikbedömning

CloudEvents kan förbättra interoperabel identitet och routingkontext. OpenTelemetry kan förbättra observationstid och trace-korrelation. En streamprocessor kan ge fönster, watermarks och stateful deduplicering.

Ingen av dem definierar automatiskt Nordics nämnare på 142 dokument, rätt terminalstatus eller vilken sen korrektion verksamheten accepterar. Teknikerna kan bära kontraktet; domänen måste fortfarande formulera det.

RESEARCH-014 testar formatmappning och RESEARCH-015 klassificerar Matrix flöden som puls, sparse-negative, per-entity, sequence eller bounded-batch. Först därefter går det att avgöra vilka nya fält eller motorer som behövs.

Praktisk granskningslista

  1. Namnge förekomsten och dess stabila identitet.
  2. Bind eventet till producent, subjekt, tenant och miljö.
  3. Separera occurred, observed/recorded och processing time.
  4. Definiera omsändning, retry och kollision.
  5. Klassificera flödet: puls, negativt, per subjekt, sekvens eller batch.
  6. Sätt freshnessbudget per flöde och boka legitim tystnad med orsak.
  7. För härledda artefakter: skilj generatedAt från varje källas validAt och låt äldsta obligatoriska källa begränsa kedjan.
  8. Ange nämnare: population, intervall, partitioner eller livscykel.
  9. Definiera watermark, allowed lateness och korrektionsregel.
  10. Gör side effects idempotenta oberoende av leveranslöftet.
  11. Visa luckor och observationsförmåga bredvid slutsatsen.

Sammanfattning

Ett event säger att en producent registrerat en förekomst. Ett färskt event säger att flödet nyligen producerat något. Inget av dessa påståenden säger automatiskt att alla relevanta förekomster eller subjekt observerats.

Matrix stalenessgrind är stark eftersom den vägrar tyst döda och obokade flöden. Den ska behållas som freshnesskontrakt, inte övertolkas som fullständighetsbevis. Beslutsrelevanta flöden behöver dessutom en uttrycklig nämnare, identitet, tidsdomäner och finalitetspolicy.

Det trovärdiga gränssnittet säger därför både hur färskt och komplett relativt vad. När en watermark passerats säger det stabil enligt policy, och när sen data anländer korrigerar det historiken additivt.

Läranderesultat

Efter kapitlet ska studenten kunna:

  • skilja eventvaliditet, korrelation, färskhet och fullständighet,
  • välja rätt fullständighetskontrakt för olika flödestyper,
  • analysera event-, observations- och processing time,
  • modellera retries och dubbletter utan falskt exactly-once-påstående,
  • formulera watermark och late-data-policy,
  • designa en coveragevy för både kundsystem och Matrix kontrollplan.
Från event till tids- och täckningsbedömt kunskapstillstånd
Visa diagramdefinition
flowchart LR
    O[Händelse i källsystem] -->|occurredAt| E[Event envelope]
    E --> I[Insamling]
    I -->|observed/recorded at| D[Identitet + deduplicering]
    D --> F{Färskhetskontrakt}
    F -- stale/refused --> U[Okänt eller begränsat svar]
    F -- färskt --> C{Fullständighetskontrakt}
    C -- gap/öppen gräns --> U
    C -- tillräckligt enligt policy --> W[Preliminär eller stabil bedömning]
    W --> L[Sen data / korrektion]
    L --> W

Fördjupningsmaterial

Övningar och laboration

Övningar och laboration

Övning 1: grön men ofullständig

Utgå från Nordic-fixturen. Skriv två korrekta och två felaktiga slutsatser av att WebhookDelivered är färskt 09.09. För varje slutsats, ange vilket ytterligare underlag som krävs.

Övning 2: klassificera tystnaden

Klassificera följande flöden som puls, sparse-negative, per-entity, sequence eller bounded-batch:

  • heartbeat,
  • GeneratorFailed,
  • dokumentkvitton,
  • queue offset,
  • nattlig inventering,
  • manuell approval rejection.

Föreslå freshness- och completenessregel. En regel som kräver regelbundna fel ska uttryckligen underkännas.

Övning 3: identitet och retries

Modellera tre leveranser av samma transportmeddelande och två verkliga försök att importera dokument 142. Ange event-ID, correlation ID, causation ID och idempotency key. Visa när två poster är dubbletter respektive nya förekomster.

Övning 4: watermarkförhandling

Två grupper representerar drift respektive ekonomi. Drift vill publicera Nordic-resultat efter två minuter; ekonomi kräver hög fullständighet före fakturering. Förhandla fram:

  • första resultat,
  • allowed lateness,
  • stabilitetsstatus,
  • regel för sena accepteranden,
  • regel för sena avvisanden,
  • när mänsklig grind krävs.

Laboration: event completeness gate

Indata

Använd cases/nordic-ch02-timeline.json och transformera relevanta observationer till ett event-envelope. Minst följande fält ska finnas:

source, id, type, subject, tenant, environment,
occurredAt, observedAt, correlationId, sourceRef

Skapa ett batchmanifest med de 142 förväntade dokument-ID:na.

Implementera

  1. schema- och tidszonsvalidering,
  2. unik identitet inom source,
  3. deduplicering av omsändningar,
  4. separat modell för retries,
  5. freshness per eventtyp,
  6. populationsfullständighet mot manifestet,
  7. preliminär/stabil-enligt-policy/korrigerad status,
  8. rapport över saknade subjekt och eventfördröjning.

Mutationstester

  • duplicera ett event med samma source + id,
  • ge två olika förekomster samma ID,
  • ta bort dokument 140 ur förväntad population,
  • håll flödet färskt genom att bara repetera dokument 137,
  • flytta observedAt 20 minuter efter occurredAt,
  • skicka ett avvisande efter watermark,
  • gör GeneratorFailed tyst i 60 dagar.

Lösningen ska skilja legitim tystnad, dubblett, kollision, sen data och populationslucka. Tyst grönt vid någon mutation är underkänt.

Inlämning

  • envelope- och manifestformat,
  • policy med motivering per flödestyp,
  • testresultat för samtliga mutationer,
  • coverage report för 09.10, 09.24, 09.31 och 09.33,
  • kort jämförelse med CloudEvents/OpenTelemetry utan krav på adoption.

Bedömning, 20 poäng

Del Poäng
Eventidentitet och korrelation 4
Flera tidsdomäner och late data 4
Freshness och legitim tystnad 3
Fullständighetsnämnare och gaprapport 5
Mutationstester och fail-closed-beteende 4

Godkänt kräver minst 12 poäng samt att ett färskt men ofullständigt flöde inte rapporteras som komplett.

Källor och begränsningar

Kapitelkällor

Cite-key/käll-ID Funktion Begränsning
akidau2015dataflow Event time, out-of-order-data och avvägningen correctness/latency/cost. Storskalig stream processing; Matrix behöver en mindre profil.
lamport1978time Kausal ordning i distribuerade system. Ger inte ett färdigt event-envelope.
cloudevents10 Interoperabel eventidentitet genom source + id, typ och kontext. Löser inte domänfullständighet eller exakt-en-gång-effekter.
otel-logs-data-model Skiljer Timestamp från ObservedTimestamp och erbjuder trace context. Telemetrimodell, inte Matrix sanningsmodell.
flink-watermarks Konkret watermark-, lateness- och completenesssemantik. Produktspecifik dokumentation; används som designexempel.
MATRIX-EVENT-CONTRACT Faktisk Matrix-vokabulär, tidszon och valfria subjektfält. Saknar generell sekvens-/watermarkprofil.
MATRIX-EVENT-VALIDATION Dubblettgrind för event-ID inom bundle. Bevisar inte idempotent effekt hos konsumenter.
MATRIX-EVENT-STALENESS Fail-closed policy och predikat för levande/dormanta flöden. Bedömer senaste event per typ, inte objekttäckning.
MATRIX-EVENT-STALENESS-POLICY Verkliga skillnader mellan kontinuerliga, arbetsdrivna och sällsynta flöden. Konfigurerad nulägespolicy, inte generell teori.
MATRIX-EVIDENCE-FRESHNESS Fail-closed källbokning och freshness genom hela evidenskedjan. Freshness bevisar inte completeness eller att källinnehållet är sant.
Argumentkarta

Argumentkarta: händelser, fullständighet och färskhet

Huvudtes

Eventbaserad kunskap blir beslutbar först när Matrix redovisar både att flödet lever och varför den observerade mängden är tillräcklig för den specifika frågan. Färskhet utan fullständighetsgräns kan ge en snabbt uppdaterad men systematiskt ofullständig bild.

Kedja

  1. Senaste eventet mäter flödets aktualitet, inte täckningen av förväntade event eller subjekt (CLAIM-EVENT-001).
  2. Fullständighet kräver ett deklarerat universum eller en gräns (CLAIM-EVENT-002).
  3. Händelsetid och insamlingstid behövs för att identifiera sen data (CLAIM-EVENT-003).
  4. Identitet kan hitta dubbletter men skapar inte exakt-en-gång-effekt (CLAIM-EVENT-004).
  5. Tystnadens betydelse beror på om flödet är puls, felhändelse, batch eller per-subjekt-kvitto (CLAIM-EVENT-005).
  6. En watermark gör avvägningen mellan väntetid och fullständighet explicit, men är fortfarande ett antagande (CLAIM-EVENT-006).

Motbevisande test

Om senaste event per typ ensamt kan avslöja ett borttappat Nordic-kvitto, en saknad partition och en tyst felhändelse utan ytterligare förväntningar behövs ingen separat fullständighetsmodell. Laborationen är konstruerad för att visa att så inte är fallet.

Faktagranskning och öppna beslut

Kapitelgranskning

Status: första manusutkast 2026-08-10. Intern implementations-, standard- och pedagogisk granskning gjord. Extern stream processing-/eventarkitekturreview och körbar studentlösning återstår.

Faktagranskning

  • Matrix event kräver ID, typ, occurredAt med tidszon och minst en sourceRef.
  • subjectNodeId, relatedNodeIds och bundle-generatedAt är valfria.
  • Validatorn vägrar duplicerade event-ID:n inom ett bundle.
  • Staleness bedöms per producent/eventtyp utifrån senaste giltiga occurredAt.
  • Policyn skiljer levande flöden, motiverat acceptedStale och producenter utan förväntade event.
  • Den granskade stalenessgrinden mäter inte population, sekvensluckor eller partitionstäckning.

Akademisk och standardmässig granskning

  • Dataflow används för principen om obegränsad/out-of-order-data och correctness/latency/cost, inte som krav på Google-teknik.
  • Flink används som konkret watermarkexempel och märks som produktspecifikt.
  • CloudEvents används för source + id-identitet, inte som exactly-once-garanti.
  • OpenTelemetry används för timestamp/observed timestamp och trace context, inte som generell kunskapsmodell.

Arkitekturgranskning

  • Befintlig stalenessgrind föreslås inte ersättas.
  • Fullständighetskontrakt läggs bredvid freshness per beslutsrelevant flöde.
  • Evidensartefakter skiljer generatedAt från källornas validAt; äldsta obligatoriska källa begränsar kedjans freshness och obokad källa fäller.
  • Freshnesskärnans hermetiska tester passerar, men två real-workspace-fall är röda eftersom Command Center-producenter/policy ännu inte är fullt migrerade (RESEARCH-047).
  • RESEARCH-014 kräver round-trip-test före event-schemaändring.
  • RESEARCH-015 kräver flödesklassificering före generell sequence- eller watermarkmodell.
  • Öppet: duplicate-ID-grinden är lokal per bundle; verifiera om en framtida sammanslagen eventvy behöver global (producerId, id)-grind.

Pedagogisk granskning

  • Nordic visar samma flöde som färskt men ofullständigt.
  • Tystnadsövningen motverkar naiva freshnessregler för felhändelser.
  • Laborationen kräver mutation som håller ett flöde färskt med samma subjekt.

Öppna beslut

  1. Vilka tre Matrix-flöden är först ut för completenesspilot?
  2. Ska observedAt vara kärnfält, profilfält eller lagras i ingest journal?
  3. Vilken identitet ska en omsändning behålla över adaptergränser?
  4. Hur visas "stabil enligt policy" utan att användaren läser det som absolut finalitet?
Kapitelkontrakt

Syfte

Visa varför färska event, ett levande flöde och ett fullständigt beslutsunderlag är tre olika saker. Kapitlet ger en modell för eventidentitet, flera tidsdomäner, dubbletter, luckor, tystnad, watermarks och korrektioner.

Lärandemål

Studenten ska kunna formulera ett fullständighetskontrakt, bedöma tystnad per flödestyp, skilja eventtid från observationstid, designa idempotent konsumtion och förklara finalitet som policy snarare än absolut sanning.

Fallstudiehändelse

Nordic har ett färskt dokumentflöde och friska komponenter, men bara 137 av 142 kvitton vid deadline. Två kvitton anländer senare och ett dokument avvisas. Kapitlet avgör vad som får kallas färskt, komplett och finalt.