Inside Dispatch

c4

C4 level 3: the components of the service that owns parcel state

DispatchCONTAINER BOUNDARYDelegates out-of-area parcels toRequests a retry stop fromProposes a transition toDelivers scans to [Kafka]Asks what happens nextWrites stops throughSequences with [gRPC]Reads / writes [SQL]Persists throughPublishes [Kafka]Emits throughScan consumer — [Kafka listener] — Reads parcel.scanned and orders events by when they happened, not when they arrivedScan consumer[Component: Kafka listener]Reads parcel.scanned and ordersevents by when they happened, notwhen they arrivedState machine — [Java] — The only thing that changes a parcel's status, and refuses any move the table does not permitState machine[Component: Java]The only thing that changes aparcel's status, and refuses anymove the table does not permitAttempt policy — [Java] — Decides whether a failed delivery is retried tomorrow or parked for the recipientAttempt policy[Component: Java]Decides whether a failed deliveryis retried tomorrow or parked forthe recipientRoute planner — [Java] — Places a parcel on a route and asks the routing engine to sequence itRoute planner[Component: Java]Places a parcel on a route andasks the routing engine tosequence itPartner hand-off — [Java] — Sends out-of-area parcels to a partner carrier and stops tracking themPartner hand-off[Component: Java]Sends out-of-area parcels to apartner carrier and stops trackingthemEvent publisher — [Kafka producer] — Emits parcel.delivered, parcel.attempt-failed and parcel.exception after the state change commitsEvent publisher[Component: Kafka producer]Emits parcel.delivered,parcel.attempt-failed andparcel.exception after the statechange commitsParcel repository — [JDBC] — The only component here that touches the databaseParcel repository[Component: JDBC]The only component here thattouches the databaseParcel events — [Kafka] — Where scans arrive from, and where state changes goParcel events[Queue: Kafka, external]Where scans arrive from, and wherestate changes goRelay DB — [PostgreSQL 15] — The parcel, route and scan tablesRelay DB[Database: PostgreSQL 15, external]The parcel, route and scan tablesRouting engine — [Python] — Sequences a van’s stops under time windowsRouting engine[Container: Python, external]Sequences a van’s stops under timewindowsDelegates out-of-area parcels toDelegates out-of-area parcels toRequests a retry stop fromRequests a retry stop fromProposes a transition toProposes a transition toDelivers scans to [Kafka]Delivers scans to[Kafka]Asks what happens nextAsks what happens nextWrites stops throughWrites stops throughSequences with [gRPC]Sequences with[gRPC]Reads / writes [SQL]Reads / writes[SQL]Persists throughPersists throughPublishes [Kafka]Publishes[Kafka]Emits throughEmits through
drag to pan · wheel to zoom · click a node · Esc clears

Why this is one service

  • Parcel state, attempt policy and route placement change together; splitting them would need a distributed transaction to stay correct.
  • Everything grey lives outside Dispatch and is drawn only to show where the edges go.