Detailed overview of how messages flow through the dfx framework.
Design Philosophy
The dfx framework utilizes a Transport-Agnostic architecture. The core Channel acts as a logical bridge, while specialized Transport objects handle the specifics of data movement (local memory, POSIX Message Queues, TCP, etc.).
This decoupling ensures that Nodes and their Ports do not need to know whether they are communicating with a local sibling or a process on a different machine.
Core Components
- Channel: The orchestrator. It manages delivery hooks and coordinates between source and destination.
- SourceTransport: Represents where data comes from.
- DestinationTransport: Represents where data goes to.
- Ports: The user-facing handles. An OutputPort has a LocalSource, and an InputPort has a LocalDestination.
The Transmission Sequence
The central entry point for all message movement is Channel::transmit(msg).
1. Source to Channel
A message enters the system via a SourceTransport:
- Local Source: The OutputPort invokes LocalSource::send(). This is a synchronous call that immediately triggers Channel::transmit().
- Remote Source: An external event (e.g., kernel notification on a File Descriptor) triggers the transport. The transport unpacks the raw data into a Message and calls Channel::transmit().
2. The Channel Hub
Inside Channel::transmit(), the framework:
- Executes the pre-delivery hook (if registered).
- Forwards the message to the DestinationTransport via its deliver() method.
- Executes the post-delivery hook (if registered) before returning control.
3. Channel to Destination
The DestinationTransport handles the final delivery:
- Remote Destination: The message is packed and written to the underlying communication wire (TCP, MQ, etc.).
- Local Destination: The message is stored in an internal thread-safe queue within LocalDestination.
Message Consumption
For local Nodes, the InputPort does not talk to the Channel directly. Instead:
This symmetry ensures that the OutputPort only sees a LocalSource::send() and the InputPort only sees a LocalDestination::pop(), hiding the complexity of the Channel and its hooks.