3.9 KiB
3.9 KiB
Rust Guidelines & Quirks
Concurrency & Async Locking
- Lock Poisoning & Async Safety: Use
tokio::sync::RwLockfor state shared across Tokio async tasks (such as active WebSocket clients) to avoid blocking worker threads during broadcast fanouts. For synchronous locks, prefer non-poisoning structures or recover cleanly using.unwrap_or_else(|e| e.into_inner()). - Atomic Store Write Lock Minimization: Minimize write lock duration by executing JSON serialization under read lock guards, keeping write guards strictly to in-memory state mutations.
- Two-Phase Graph Condensation: When performing summarization or condensation across stores (
condense_graph_worker), implement a two-phase commit: read non-destructively and synthesize observations first, insert into the knowledge graph, and only prune summarized source records by timestamp/content after successful insertion. - Watch-Based Non-Destructive Shutdown Channels: Use
tokio::sync::watchrather thantokio::sync::mpscfor cancellation signaling to allow multiple workers to observe shutdown state without consuming or starving sibling workers. - Redb Transient Lock Resilience: Implement retry loops with exponential backoff on table or database lock contention before aborting or panicking.
- Safe RPC Request Tracking: Clean up pending request maps (
PENDING_REQUESTS.remove(&msgid)) upon timeouts or channel disconnects to prevent orphan memory leaks. - Panic-Free Architecture: Avoid raw
.unwrap()in production runtime paths. Use.unwrap_or_default(), or properResultpropagation for runtime operations. - Background Worker Task Supervision: Always track
tokio::task::JoinHandlehandles for background workers (ttl_sweeper_worker,index_committer_worker,condense_graph_worker) and log thread exit or panic events cleanly. - Offload Heavy Index Rebuilds: In
MemoryState::rebuild_index, offload full graph cloning and Tantivy document re-indexing intotokio::task::spawn_blockingto avoid stalling async worker threads.
Embedding & Memory Optimizations
- Dynamic Character Batching: In embedding generation (
generate_embeddings_async), dynamically chunk batches based on total character size (e.g. 16,384 chars) rather than static item counts to prevent OOM spikes on large files while maximizing SIMD throughput. - SIMD Cosine Similarity: Compute dot-product and norm accumulators in single-pass iterator folds to facilitate vector auto-vectorization across CPU instruction sets (
AVX2/NEON). - Memory Truncation Bounds: Enforce a 4KB ceiling on telemetry detail strings (
ActivityRecord,TerminalHistory) before queuing items into ring buffers to bound heap usage.
IDE & Rust-Analyzer Quirks
- Boolean NOT Operator (E0600): Avoid using the unary
!operator on complex boolean expressions inside closures (e.g.,!(a == b && c == d)). Rewrite these expressions using De Morgan's laws (e.g.,a != b || c != d). - Option::None Shadowing: If
rust-analyzerthrows anon_snake_casewarning forNoneduring pattern matching (often caused by wildcard imports likeuse crate::models::*;), explicitly namespace asstd::option::Option::None. - Deep Cloning across Thread Boundaries: Construct target primitive payloads or target structs on the main thread before moving into
tokio::task::spawn_blockingclosures to avoid cloning massive structs across thread boundaries.
Windows MSVC & Test Concurrency
- ONNX Runtime / Fastembed Concurrency Resilience: ONNX Runtime (
ort.dllviafastembed) model initialization is strictly managed via a thread-safe singleton (OnceLock<Mutex<TextEmbedding>>) behind a process-wideINIT_MUTEX. The historical0xc0000374 STATUS_HEAP_CORRUPTIONcrash under uncoordinated C-ABI initializations is fully resolved. Full parallel test execution (cargo test --workspaceorcargo nextest run --workspace) across all CPU cores without--test-threads=1is safe, recommended, and standard across all platforms.