Skip to main content

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:

ServiceImageRolePort
frontendnginx:1.27-alpine (multi-stage)Serves React SPA3000→80
mpi-masterRust + OpenMPIHTTP API + MPI rank 08000
mpi-workerRust + OpenMPIMPI 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:

  1. Renders the WebGL canvas
  2. Handles user input
  3. Receives finished results from the Web Worker

All WASM computation (parse, style, path building) runs in the worker.