Skip to main content

Payload Lifecycle

This page traces the exact, step-by-step sequence a payload follows from the sending application, through the simulated network, to the receiving application โ€” in both PULL and PUSH mode โ€” plus the initialization handshake every client performs before any payload can flow, and the shutdown sequence.

Complete Payload Lifecycle (PULL Mode)โ€‹

The four steps that move a payload from sender application โ†’ simulated network โ†’ receiver application:

โ‘  AppA.send("B", data)
โ”œโ”€โ”€ Comms.store(payload) โ†’ payload_key
โ”œโ”€โ”€ [SEND message: payload_key + metadata] โ†’ Daemon
โ””โ”€โ”€ Daemon stores payload entry in TX buffer

โ‘ก SimClient.fetch()
โ”œโ”€โ”€ [FETCH Request] โ†’ Daemon
โ”œโ”€โ”€ Daemon searches TX buffer
โ”œโ”€โ”€ [FETCH Response: payload_key + metadata] โ† Daemon
โ”œโ”€โ”€ (optional) SimClient.checkOut(key) โ†’ payload
โ””โ”€โ”€ Transmit payload through simulated network

โ‘ข SimClient.post("A", "B", payload)
โ”œโ”€โ”€ Comms.store(payload) โ†’ payload_key (if use_db)
โ”œโ”€โ”€ [POST message: payload_key + metadata] โ†’ Daemon
โ””โ”€โ”€ Daemon stores payload entry in RX buffer

โ‘ฃ AppB.receive()
โ”œโ”€โ”€ [RECV Request] โ†’ Daemon
โ”œโ”€โ”€ Daemon searches RX buffer
โ”œโ”€โ”€ [RECV Response: payload_key + metadata] โ† Daemon
โ”œโ”€โ”€ Comms.checkOut(key) โ†’ payload
โ””โ”€โ”€ Payload available to application

Complete Payload Lifecycle (PUSH Mode)โ€‹

In PUSH mode, the daemon proactively FORWARDs payload entries to clients. No polling is needed.

โ‘  AppA.send("B", data)
โ”œโ”€โ”€ Comms.store(payload) โ†’ payload_key
โ””โ”€โ”€ [SEND message] โ†’ Daemon
โ””โ”€โ”€ Daemon immediately [FORWARD]s โ†’ SimClient.listen()

โ‘ก SimClient.listen() receives FORWARD
โ”œโ”€โ”€ (optional) payload checkout from cache
โ””โ”€โ”€ Transmit payload through simulated network

โ‘ข SimClient.post("A", "B", payload)
โ””โ”€โ”€ [POST message] โ†’ Daemon
โ””โ”€โ”€ Daemon immediately [FORWARD]s โ†’ AppB.listen()

โ‘ฃ AppB.listen() receives FORWARD
โ”œโ”€โ”€ Comms.checkOut(key) โ†’ payload
โ””โ”€โ”€ Payload available to application

Notice the structural symmetry between the two modes โ€” the same four logical steps occur, but PULL mode has each client actively request ("Request" / "Response"), while PUSH mode has the daemon proactively deliver ("FORWARD"). See System Modes for when to choose each.

Initialization Handshakeโ€‹

Before any payload can flow, each client performs a registration handshake with the daemon:

Client:
1. Construct sub-channel ports (ctrl, send, recv)
2. Open temporary connection to daemon
3. Send INIT message with: { identifier, address, ch_CTRL, ch_SEND, ch_RECV }

Daemon:
4. Parse INIT message
5. Register client in client registry
6. Construct persistent sub-channel connections to client
7. Respond with INIT message containing: { sys_mode, sim_mode, use_db, db_address, db_port, db_num }

Client:
8. Receive daemon's INIT response
9. Save configuration parameters
10. Connect to Redis cache at configured address/port
11. Ready to send/receive/fetch/post

This dynamic handshake ensures that the same configuration is understood by the daemon and all endpoints, preventing inconsistent system behavior.

Shutdownโ€‹

Any framework component โ€” daemon or client โ€” can initiate shutdown by sending an EXIT message to the daemon. The daemon then:

  1. Disseminates the EXIT message throughout the system
  2. Tears down all transport connections
  3. Clients terminate their Redis connections

Go Deeperโ€‹

  • Message Flow โ€” the operations and status codes referenced in each step above
  • Deep Architecture โ€” why the daemon never holds payload content, and the abstractions (Comms, DBConnector) behind store() / checkOut()
  • Protocol โ†’ Initialization Flow โ€” the same handshake shown with full Protobuf message fields