120k Lines of Rust: Inside the Nosdesk Backend
2 days ago
- #Rust Programming
- #Backend Architecture
- #Systems Design
- The backend of Nosdesk is built with about 120,000 lines of Rust across 260 modules, supported by over 1,000 tests.
- Key technologies include Actix-web, Diesel with Postgres, Redis, and Tokio, all packaged as a single binary deployed via Docker Compose.
- Three core principles guide development: using the type system to prevent errors, separating pure logic from I/O for easier testing, and writing comments that explain the reasoning behind decisions.
- Data handling uses pipelines with bounded buffers and back-pressure to manage memory and load, such as streaming bootstrap syncs to avoid memory spikes.
- The sync engine relies on a single append-only log (sync_actions) for consistency across HTTP delta sync, live pushes, and audit trails, with Postgres LISTEN/NOTIFY for real-time updates.
- Live updates are delivered via Server-Sent Events with a broadcast bus, using tokio::broadcast and ring buffers for replay, and include mechanisms for deduplication, heartbeats, and lag handling.
- Real-time collaborative editing uses CRDTs via the yrs library, with deterministic client IDs to prevent issues after restarts and panic isolation with catch_unwind for safety.
- The email subsystem is designed for reliability with a durable queue, circuit breakers, full-jitter backoff retries, and at-least-once delivery to handle failures gracefully.
- Multi-tenancy is enforced through type-safe database connections (TenantConn and PlatformConn) and Row-Level Security, making cross-tenant operations explicit and preventing data leaks.
- Security measures include SSRF-safe HTTP with custom DNS resolvers, equal-work login to prevent timing attacks, and encryption with domain separation using AES-256-GCM.
- Testing focuses on pure functions for critical areas like validation and parsing, with database tests that roll back transactions and lint-as-tests to enforce rules like sync event emission.
- Remaining tasks before v1 include refactoring route registration, implementing graceful shutdown, removing an unsafe Send/Sync impl, and improving error type consistency.
- The overall philosophy emphasizes upfront effort to make failures unrepresentable, leveraging Rust's type system and compiler to build robust and maintainable systems.