perf: cache getProjectSchema results in memory The on-demand fallback parses all ~490 files through tree-sitter on every request, taking 8+ seconds. Results are now cached keyed by (did, repo, commit_oid). First request parses; subsequent requests return instantly. Cache invalidates naturally when a new commit is pushed (different commit_oid = different cache key).
Author: Aaron Steven White
Commit
c36f1890546a58036f5b3af48dc973998795f900Parent: 1f39318fd1
Structural diff unavailable
These commits were pushed via plain git push, so no pre-parsed
schemas are available. Install git-remote-cospan and re-push via panproto:// to
see scope-level changes, breaking change detection, and semantic diffs.
brew install panproto/tap/git-remote-cospan1 file changed +26 -5
@@ -8,11 +8,16 @@
88 //! stored schema's vertex IDs (which encode the file path prefix). 99 1010 use std::collections::HashMap; 11-use std::sync::Arc; 11+use std::sync::{Arc, LazyLock, Mutex}; 1212 1313 use axum::Json; 1414 use axum::extract::{Query, State}; 1515 use panproto_core::vcs::{Object, Store}; 16+ 17+/// Cache for on-demand project schema results. Keyed by (did, repo, commit_oid). 18+/// Avoids reparsing 490 files on every page load. 19+static SCHEMA_CACHE: LazyLock<Mutex<HashMap<String, serde_json::Value>>> = 20+ LazyLock::new(|| Mutex::new(HashMap::new())); 1621 use serde::Deserialize; 1722 use serde_json::{Value, json}; 1823
@@ -70,6 +75,14 @@ pub async fn get_project_schema(
7075 _ => None, 7176 }); 7277 78+ // Check cache first (avoids reparsing 490 files on every page load). 79+ let cache_key = format!("{}:{}:{}", params.did, params.repo, commit_oid); 80+ if let Ok(cache) = SCHEMA_CACHE.lock() { 81+ if let Some(cached) = cache.get(&cache_key) { 82+ return Ok(Json(cached.clone())); 83+ } 84+ } 85+ 7386 // Walk the git tree for file listing and language detection. 7487 let commit = mirror 7588 .find_commit(commit_oid)
@@ -218,7 +231,7 @@ pub async fn get_project_schema(
218231 219232 let parsed_count = file_vertex_counts.len(); 220233 221- return Ok(Json(json!({ 234+ let result = json!({ 222235 "commit": commit_oid.to_string(), 223236 "protocol": protocol, 224237 "totalVertexCount": total_vc,
@@ -227,7 +240,11 @@ pub async fn get_project_schema(
227240 "parsedFileCount": parsed_count, 228241 "languages": languages, 229242 "fileSchemas": file_schemas, 230- }))); 243+ }); 244+ if let Ok(mut cache) = SCHEMA_CACHE.lock() { 245+ cache.insert(cache_key, result.clone()); 246+ } 247+ return Ok(Json(result)); 231248 } 232249 233250 // Fallback: no vcs store data. Parse all files on demand.
@@ -320,7 +337,7 @@ pub async fn get_project_schema(
320337 .map(|(name, _)| name.clone()) 321338 .unwrap_or_default(); 322339 323- Ok(Json(json!({ 340+ let result = json!({ 324341 "commit": commit_oid.to_string(), 325342 "protocol": protocol, 326343 "totalVertexCount": total_vc,
@@ -329,5 +346,9 @@ pub async fn get_project_schema(
329346 "parsedFileCount": parsed_count, 330347 "languages": languages, 331348 "fileSchemas": file_schemas, 332- }))) 349+ }); 350+ if let Ok(mut cache) = SCHEMA_CACHE.lock() { 351+ cache.insert(cache_key, result.clone()); 352+ } 353+ Ok(Json(result)) 333354 }