ADR-005: Dual HTTP + gRPC Server Architecture
Date: 2024-01-10
Status: Accepted
Context
SynDB serves two distinct client populations with different transport needs:
- Web UI and REST clients require HTTP/JSON endpoints for CRUD operations on metadata, user management, and administrative tasks.
- Data science clients require high-performance Apache Arrow Flight (gRPC) for streaming large analytical datasets (see ADR-004).
Running these as separate binaries would double deployment artifacts, duplicate shared state (database connection pools, S3 clients, configuration), and complicate service discovery and health checking.
Decision
Run both Axum HTTP (port 8080) and tonic Flight gRPC (port 50051)
servers in the same binary process. Both servers share a single AppState
containing database connections, S3 client, PASETO secret, and application
settings.
Concurrent operation is achieved via tokio::select! on both server futures,
with a shared shutdown signal (broadcast channel) for coordinated graceful
termination.
Consequences
Positive:
- Single deployment artifact (one container image, one binary) simplifies CI/CD and operational management.
- Shared connection pools for PostgreSQL, ClickHouse, and S3 reduce total resource consumption versus two separate processes.
- Both servers validate PASETO tokens with the same in-memory secret – no secret distribution problem.
- Health checks and readiness probes need only target one process.
Negative:
- A crash in either server’s accept loop brings down both protocols.
- Graceful shutdown must coordinate two listeners; a stalled gRPC stream can delay HTTP shutdown and vice versa.
- Resource contention (thread pool, memory) between HTTP and gRPC workloads is harder to isolate than with separate processes.