top of page
Search

TMF Forum quick notes:

  • Writer: Mark Kendall
    Mark Kendall
  • Jan 7
  • 2 min read


Kafka = system of record (truth)

and any “queryability” comes from your own subscriber-built read model (even if that read model is lightweight/in-memory at first).


Here’s the clean way to think about it, plus the practical patterns that keep it from getting sloppy.



What you’ve built (in one sentence)



TMF services emit immutable facts to Kafka, and TMF688 (or a companion component) replays/consumes those facts to answer “what happened?” with observed history, not guesses.



The pattern name



This is essentially event sourcing + consumer-driven projections (a CQRS-ish split), even if you’re not calling it that.



The key rule to keep it “single source of truth”



Kafka is the SoT only if:


  • events are append-only (no “fixup” by overwriting meaning)

  • events have stable IDs (eventId) + a correlationId

  • you can rebuild any queryable view by replaying from earliest (or from a checkpoint)




How you query Kafka without “Kafka as a database”



What you described (“subscribe ourselves and query that”) is correct, but make it explicit as two layers:



1) The immutable log (Kafka topics)



You store:


  • recordType: INGRESS | EXECUTION

  • outcome: SUCCESS | ERROR | IN_PROGRESS | UNKNOWN

  • stage, attempt, timestamps, error object, etc.




2) The query layer (your own projection)



You build a local “materialized view” from the stream, optimized for the 4 GETs:


  • by correlationId → timeline array

  • by eventId → single record

  • by messageId → ingress record

  • search filters → index fields (eventType/stage/outcome/time)



This projection can be:


  • in-memory (fast, but volatile)

  • persisted (RocksDB / Redis / Mongo / Postgres / Elasticsearch — doesn’t matter, because it’s not SoT)

  • rebuilt anytime by replay




The only real gotcha



If your projection is only “subscribe and keep in memory”, then:


  • restarts lose history unless you replay

  • replays require knowing where to start (consumer group offsets) or using a reset/replay mode

  • you need a retention policy that still lets you replay “far enough back”



So the operational question becomes:


“How far back do we need to answer TMF688 queries?”


If it’s “days/weeks”, Kafka retention might be enough.

If it’s “months/years”, you’ll still likely want a persisted projection store — but Kafka remains SoT.



How this gets you from implied → observed behavior



This is the big win:


  • Implied: “We stored the inbound canonical message, so it probably worked.”

  • Observed: “We have an execution fact stream that includes validation, adapter calls, retries, DLQ, final outcomes.”



Your TMF688 responses become:


  • honest timelines

  • error details when present

  • “unknown/unobserved” when the stream never shows a fact past ingress




One implementation detail you should bake in now



Add a consistent event envelope across all services, so replay/projections are painless:


  • eventId (unique)

  • correlationId

  • recordType (INGRESS/EXECUTION)

  • stage

  • outcome

  • timestamp

  • payload?

  • error?

  • metadata (producer/version/spec)



That’s it. Everything else is optional.





 
 
 

Recent Posts

See All

Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
Post: Blog2_Post

Subscribe Form

Thanks for submitting!

©2020 by LearnTeachMaster DevOps. Proudly created with Wix.com

bottom of page