refactor: apply rust best practices and fix memory optimizations
- Optimized memory allocation in router.rs by offloading JSON serialization to spawn_blocking and using references. - Prevented full graph duplication on startup in state.rs index rebuild. - Eliminated massive String allocations in QueryGraphPathHandler BFS loops. - Avoided temporary Strings in VisualizeGraphHandler via inline writing. - Fixed O(N) full-graph deduplication in MergeEntitiesHandler to scale efficiently.
This commit is contained in:
1 parent
251757f8fc
commit
37003be620
17 files changed
+399
-198
No files matched your search
+30
-22
@@ -195,30 +195,39 @@ impl MemoryHandler {
|
||||
}
|
||||
"resources/read" => {
|
||||
let params = req.get("params").unwrap_or(&serde_json::Value::Null);
|
||||
let uri = params.get("uri").and_then(|u| u.as_str()).unwrap_or("");
|
||||
|
||||
let text = match uri {
|
||||
let uri = params
|
||||
.get("uri")
|
||||
.and_then(|u| u.as_str())
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
|
||||
let state_clone = Arc::clone(&self.state);
|
||||
let uri_clone = uri.clone();
|
||||
let text = match tokio::task::spawn_blocking(move || match uri_clone.as_str() {
|
||||
"memory://graph/entities" => {
|
||||
let graph = self.state.graph.cache.read().unwrap();
|
||||
let data: Vec<_> = graph.entities.values().cloned().collect();
|
||||
serde_json::to_string_pretty(&data).unwrap_or_default()
|
||||
let graph = state_clone.graph.cache.read().unwrap();
|
||||
let data: Vec<_> = graph.entities.values().collect();
|
||||
Some(serde_json::to_string_pretty(&data).unwrap_or_default())
|
||||
}
|
||||
"memory://graph/relations" => {
|
||||
let graph = self.state.graph.cache.read().unwrap();
|
||||
let data = graph.relations.clone();
|
||||
serde_json::to_string_pretty(&data).unwrap_or_default()
|
||||
let graph = state_clone.graph.cache.read().unwrap();
|
||||
let data = &graph.relations;
|
||||
Some(serde_json::to_string_pretty(&data).unwrap_or_default())
|
||||
}
|
||||
"memory://tasks/active" => {
|
||||
let tasks = self.state.tasks.cache.read().unwrap();
|
||||
let data: Vec<_> = tasks.iter()
|
||||
let tasks = state_clone.tasks.cache.read().unwrap();
|
||||
let data: Vec<_> = tasks
|
||||
.iter()
|
||||
.filter(|t| t.status != "completed" && t.status != "done")
|
||||
.cloned()
|
||||
.collect();
|
||||
serde_json::to_string_pretty(&data).unwrap_or_default()
|
||||
}
|
||||
_ => {
|
||||
return Some(crate::mcp::error(id, -32602, "Resource not found"));
|
||||
Some(serde_json::to_string_pretty(&data).unwrap_or_default())
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(Some(text)) => text,
|
||||
_ => return Some(crate::mcp::error(id, -32602, "Resource not found")),
|
||||
};
|
||||
|
||||
let payload = serde_json::json!({
|
||||
@@ -245,7 +254,7 @@ impl MemoryHandler {
|
||||
"prompts/get" => {
|
||||
let params = req.get("params").unwrap_or(&serde_json::Value::Null);
|
||||
let name = params.get("name").and_then(|n| n.as_str()).unwrap_or("");
|
||||
|
||||
|
||||
if name == "analyze_tech_debt" {
|
||||
let payload = serde_json::json!({
|
||||
"messages": [
|
||||
@@ -318,19 +327,19 @@ impl MemoryHandler {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use tempfile::tempdir;
|
||||
use serde_json::json;
|
||||
use tempfile::tempdir;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_memory_handler_tools_registration() {
|
||||
let dir = tempdir().unwrap();
|
||||
let state = Arc::new(MemoryState::new(dir.path().to_str().unwrap()));
|
||||
let handler = MemoryHandler::new(state);
|
||||
|
||||
|
||||
// Assert some known tools are registered
|
||||
assert!(handler.tools.contains_key("create_entities"));
|
||||
assert!(handler.tools.contains_key("add_task"));
|
||||
|
||||
|
||||
// Ensure we can fetch list of tools
|
||||
let list_tools_req = json!({
|
||||
"jsonrpc": "2.0",
|
||||
@@ -338,11 +347,10 @@ mod tests {
|
||||
"method": "tools/list",
|
||||
"params": {}
|
||||
});
|
||||
|
||||
|
||||
let res_list = handler.handle_request(list_tools_req).await.unwrap();
|
||||
assert_eq!(res_list["jsonrpc"], "2.0");
|
||||
assert_eq!(res_list["id"], 1);
|
||||
assert!(res_list["result"]["tools"].as_array().unwrap().len() > 10);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user