refactor(mcp): strip sse fallback architecture in favor of pure websockets and fix nvim NDJSON bug
This commit is contained in:
1 parent
0e29b12ac8
commit
3716c3e698
33 files changed
+2082
-1756
No files matched your search
@@ -58,3 +58,80 @@ impl<T: DeserializeOwned + Default + Serialize + Clone + Send + 'static> Store<T
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
#[derive(Serialize, serde::Deserialize, Clone, Default, PartialEq, Debug)]
|
||||
struct TestData {
|
||||
name: String,
|
||||
value: i32,
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_store_read_write() {
|
||||
let temp_file = NamedTempFile::new().unwrap();
|
||||
let db = Database::create(temp_file.path()).unwrap();
|
||||
|
||||
let write_txn = db.begin_write().unwrap();
|
||||
{
|
||||
write_txn.open_table(STORE_TABLE).unwrap();
|
||||
}
|
||||
write_txn.commit().unwrap();
|
||||
|
||||
let db = Arc::new(db);
|
||||
let store = Store::<TestData>::new("test_key", db.clone());
|
||||
|
||||
assert_eq!(store.read(), TestData::default());
|
||||
|
||||
store.modify(|data| {
|
||||
data.name = "Hello".to_string();
|
||||
data.value = 42;
|
||||
});
|
||||
|
||||
// Need to wait for spawn_blocking to finish
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
||||
|
||||
assert_eq!(store.read(), TestData { name: "Hello".to_string(), value: 42 });
|
||||
|
||||
// Load again to verify persistence
|
||||
let store2 = Store::<TestData>::new("test_key", db.clone());
|
||||
assert_eq!(store2.read(), TestData { name: "Hello".to_string(), value: 42 });
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
|
||||
async fn test_store_concurrency() {
|
||||
let temp_file = NamedTempFile::new().unwrap();
|
||||
let db = Database::create(temp_file.path()).unwrap();
|
||||
|
||||
let write_txn = db.begin_write().unwrap();
|
||||
{
|
||||
write_txn.open_table(STORE_TABLE).unwrap();
|
||||
}
|
||||
write_txn.commit().unwrap();
|
||||
|
||||
let db = Arc::new(db);
|
||||
let store = Arc::new(Store::<TestData>::new("concurrent_key", db.clone()));
|
||||
|
||||
let mut handles = vec![];
|
||||
for _ in 0..50 {
|
||||
let s = store.clone();
|
||||
handles.push(tokio::spawn(async move {
|
||||
s.modify(|data| {
|
||||
data.value += 1;
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for h in handles {
|
||||
h.await.unwrap();
|
||||
}
|
||||
|
||||
// Wait for all blocking writes to flush
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
|
||||
|
||||
assert_eq!(store.read().value, 50);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user