Architecture Overview
System Diagram
┌─────────────────────────────────────────────────────────────────┐
│ Browser (Client) │
│ │
│ ┌──────────────────┐ ┌───────────────────────────────┐ │
│ │ React + Vite │ │ Web Worker │ │
│ │ (Main Thread) │ │ │ │
│ │ │◄────►│ WASM (graph-wasm.wasm) │ │
│ │ Reagraph/WebGL │ │ • parse_edge_list │ │
│ │ 3D/2D Canvas │ │ • parse_adjacency_list │ │
│ │ Animation │ │ • build_neighbor_map │ │
│ │ Node Search │ │ • build_path_sets │ │
│ └────────┬─────────┘ │ • compute_node_styles │ │
│ │ │ • compute_edge_styles │ │
│ │ HTTP/REST └───────────────────────────────┘ │
└───────────┼─────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────┐
│ Docker Network (172.28.1.0/24) │
│ │
│ ┌────────────────────────────────┐ │
│ │ mpi-master (172.28.1.2) │ │
│ │ │ │
│ │ Rocket HTTP Server :8000 │◄────────────────────────┐│
│ │ MPI Rank 0 (master) │ bincode over TCP/MPI ││
│ │ Algorithms: runs + merges │ ││
│ └────────────────────────────────┘ ││
│ ││
│ ┌────────────────────────────────┐ ││
│ │ mpi-worker (172.28.1.3) │ ││
│ │ MPI Rank 1 (worker) │◄────────────────────────┘│
│ │ Algorithms: receives + runs │ │
│ └────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
Service Decomposition
The system is deployed as three Docker services via Docker Compose:
| Service | Image | Role | Port |
|---|---|---|---|
frontend | nginx:1.27-alpine (multi-stage) | Serves React SPA | 3000→80 |
mpi-master | Rust + OpenMPI | HTTP API + MPI rank 0 | 8000 |
mpi-worker | Rust + OpenMPI | MPI rank 1+ (compute) | — |
The master and worker containers share a private bridge network (172.28.1.0/24) with static IPs, enabling direct MPI communication. The master exposes port 8000 to the host; the worker is not externally reachable.
Data Flow: End-to-End Request
1. User uploads graph file (edge list or adjacency list format)
2. Browser: FileReader reads file as text string
3. Web Worker: receives {content, format}
└─ WASM parse_edge_list(content) → JSON
└─ Deserialize → ParsedGraph { nodes, edges, neighborMap, ... }
└─ postMessage result to main thread
4. React: parsedGraph state set → GraphView renders
└─ WASM compute_node_styles(...) → degree-colored nodes
└─ Reagraph renders WebGL scene
5. User selects algorithm (e.g., Dijkstra), enters start node, clicks Execute
6. Browser: POST /process_file with FormData {file, request: JSON}
7. mpi-master (Rank 0):
└─ Rocket handler receives file → writes to /tmp
└─ spawn_blocking → run_distributed_algorithm(...)
└─ parse file → Graph struct
└─ partition_graph() → one full-graph partition per process
└─ send partition+task to mpi-worker (Rank 1) via MPI_Send
└─ execute Dijkstra locally on partition[0]
└─ receive result from worker via MPI_Recv
└─ merge_results(): prefer worker path
└─ return TaskResult { path, distances }
└─ delete /tmp file
└─ JSON response { path, distances, mpi_processes: 2, mpi_mode: "distributed" }
8. Browser: receives result
└─ WASM build_path_sets(path, "dijkstra") → pathNodeSet, pathEdgeSet
└─ WASM compute_node_styles(..., pathNodesJson, startNode, "") → updated colors
└─ WASM compute_edge_styles(..., pathEdgeSetJson, "[]") → updated edge colors
└─ Reagraph re-renders with highlighted path
9. User clicks Play → animation timer starts
└─ animStep increments every 100ms
└─ visiblePathNodes = path[0..animStep]
└─ WASM recomputes node styles each tick
└─ Reagraph renders progressive path reveal
Key Design Principles
Rust Across the Stack
Using Rust for both backend and WASM layer provides:
- Type safety — graph algorithms and serialization are type-checked end-to-end
- Performance — zero-cost abstractions, no GC, predictable latency
- Memory safety — no buffer overflows, critical for a service accepting user-uploaded files
Computation Placement
- Heavy algorithmic work → Rust on the MPI cluster
- File parsing + rendering prep → WASM in a Web Worker (off main thread)
- Visualization → WebGL GPU rendering via Three.js
No Main Thread Blocking
The React main thread only:
- Renders the WebGL canvas
- Handles user input
- Receives finished results from the Web Worker
All WASM computation (parse, style, path building) runs in the worker.