Audience: Architects, implementers. Use: Relate BSFG core logic and adapters to the hexagonal architecture pattern.
What is Hexagonal Architecture?
Hexagonal Architecture = Ports and Adapters (Alistair Cockburn).
A software architecture pattern that decouples your application core from external concerns such as databases, APIs, UIs, and frameworks by defining narrow interface boundaries called ports and interchangeable implementations called adapters.
Why "hexagonal"?
The visual metaphor. The application sits at the center of a hexagon; each flat side exposes a Port (interface contract) without preference for "left" (UI) vs. "right" (database) vs. "top" (external service). The symmetry emphasizes that all dependencies are equivalent, not "primary" vs. "secondary" as in layered architecture.
The anatomy
- Port: An interface, the what. It defines "I need append-only storage with offset tracking." In BSFG:
StoreBuffer,ForwardBuffer,CursorTracker. - Adapter: The implementation, the how. It satisfies the port using concrete technology. In BSFG: Kafka, PostgreSQL, S3, Redis adapters.
- Application Core: The BSFG handoff protocol and cursor advancement logic. It knows only the Ports, never the Adapters.
The "hexagonal" in BSFG
The four buffers, ISB, IFB, ESB, and EFB, are logical roles: architectural responsibilities for durability and deduplication. The actual Ports are the narrow interfaces they implement: StoreBuffer (for store buffers), ForwardBuffer (for forward buffers), and CursorTracker. The "Fast swappability" objective means that swapping PostgreSQL for Kafka, or Redis for S3, changes only the Adapter implementations of these ports, not the core logic inside.
Visual
[Kafka Adapter]
|
| implements
v
[OPC UA] -> [ Port: StoreBuffer ] -> [ BSFG Core ] -> [ Port: ForwardBuffer ] -> [ Redis Adapter]
^ |
[PG Adapter] [Port: CursorTracker]
|
[S3 Adapter]
The hexagon is the boundary. The ports are the flat edges where external concerns plug in without the core knowing which specific technology is outside.
Benefits applied to BSFG
Testability: Mock the ports. No need for a running Kafka or PostgreSQL to test the handoff protocol.
- Write tests against the
StoreBufferinterface using an in-memory adapter. - Verify cursor advancement logic without external infrastructure.
Deployment flexibility: Choose backends for each buffer independently. Use Redis for IFB in development, PostgreSQL in production.
- Different cost and performance tradeoffs per environment.
- Swap backends without changing protocol logic.
Fast swappability: A new backend technology only needs an implementation of the relevant port.
- No need to redesign the handoff protocol.
- New technologies can be integrated without architecture disruption.
Key insight
The key point is decoupling. BSFG's protocol logic is independent of whether durability is provided by Kafka, PostgreSQL, S3, or something else.