feat: make open_store async and add root store caching
This commit is contained in:
@@ -47,7 +47,7 @@ fn cmd_create_store(node: &Node, _store: Option<&StoreHandle>, _endpoint: Option
|
|||||||
match node.create_store() {
|
match node.create_store() {
|
||||||
Ok(store_id) => {
|
Ok(store_id) => {
|
||||||
println!("Created store: {}", store_id);
|
println!("Created store: {}", store_id);
|
||||||
match node.open_store(store_id) {
|
match block_async(node.open_store(store_id)) {
|
||||||
Ok((handle, _)) => {
|
Ok((handle, _)) => {
|
||||||
println!("Switched to new store");
|
println!("Switched to new store");
|
||||||
CommandResult::SwitchTo(handle)
|
CommandResult::SwitchTo(handle)
|
||||||
@@ -75,7 +75,7 @@ fn cmd_use_store(node: &Node, _store: Option<&StoreHandle>, _endpoint: Option<&L
|
|||||||
};
|
};
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
match node.open_store(store_id) {
|
match block_async(node.open_store(store_id)) {
|
||||||
Ok((handle, info)) => {
|
Ok((handle, info)) => {
|
||||||
if info.entries_replayed > 0 {
|
if info.entries_replayed > 0 {
|
||||||
println!("Replayed {} entries ({:.2?})", info.entries_replayed, start.elapsed());
|
println!("Replayed {} entries ({:.2?})", info.entries_replayed, start.elapsed());
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ impl Node {
|
|||||||
pub async fn open_root_store(&self) -> Result<Option<StoreInfo>, NodeError> {
|
pub async fn open_root_store(&self) -> Result<Option<StoreInfo>, NodeError> {
|
||||||
match self.meta.root_store()? {
|
match self.meta.root_store()? {
|
||||||
Some(id) => {
|
Some(id) => {
|
||||||
let (handle, info) = self.open_store(id)?;
|
let (handle, info) = self.open_store(id).await?;
|
||||||
*self.root_store.write().await = Some(handle);
|
*self.root_store.write().await = Some(handle);
|
||||||
Ok(Some(info))
|
Ok(Some(info))
|
||||||
}
|
}
|
||||||
@@ -201,7 +201,7 @@ impl Node {
|
|||||||
self.meta.set_root_store(store_id)?;
|
self.meta.set_root_store(store_id)?;
|
||||||
|
|
||||||
// Open the store and write our node info as separate keys
|
// Open the store and write our node info as separate keys
|
||||||
let (handle, _) = self.open_store(store_id)?;
|
let (handle, _) = self.open_store(store_id).await?;
|
||||||
let pubkey_hex = hex::encode(self.node.public_key_bytes());
|
let pubkey_hex = hex::encode(self.node.public_key_bytes());
|
||||||
|
|
||||||
// Store node metadata as separate keys
|
// Store node metadata as separate keys
|
||||||
@@ -235,7 +235,7 @@ impl Node {
|
|||||||
self.meta.set_root_store(store_id)?;
|
self.meta.set_root_store(store_id)?;
|
||||||
|
|
||||||
// Open and cache the handle
|
// Open and cache the handle
|
||||||
let (handle, _) = self.open_store(store_id)?;
|
let (handle, _) = self.open_store(store_id).await?;
|
||||||
*self.root_store.write().await = Some(handle.clone());
|
*self.root_store.write().await = Some(handle.clone());
|
||||||
|
|
||||||
// Publish our name to the store
|
// Publish our name to the store
|
||||||
@@ -437,7 +437,19 @@ impl Node {
|
|||||||
Ok(store_id)
|
Ok(store_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_store(&self, store_id: Uuid) -> Result<(StoreHandle, StoreInfo), NodeError> {
|
pub async fn open_store(&self, store_id: Uuid) -> Result<(StoreHandle, StoreInfo), NodeError> {
|
||||||
|
// Check if this store is already cached as root_store
|
||||||
|
{
|
||||||
|
let guard = self.root_store.read().await;
|
||||||
|
if let Some(ref handle) = *guard {
|
||||||
|
if handle.id() == store_id {
|
||||||
|
let info = StoreInfo { store_id, entries_replayed: 0 };
|
||||||
|
return Ok((handle.clone(), info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not cached, open it fresh
|
||||||
self.data_dir.ensure_store_dirs(store_id)?;
|
self.data_dir.ensure_store_dirs(store_id)?;
|
||||||
|
|
||||||
let author_id_hex = hex::encode(self.node.public_key_bytes());
|
let author_id_hex = hex::encode(self.node.public_key_bytes());
|
||||||
@@ -661,7 +673,7 @@ mod tests {
|
|||||||
let stores = node.list_stores().expect("list failed");
|
let stores = node.list_stores().expect("list failed");
|
||||||
assert!(stores.contains(&store_id));
|
assert!(stores.contains(&store_id));
|
||||||
|
|
||||||
let (handle, _) = node.open_store(store_id).expect("Failed to open store");
|
let (handle, _) = node.open_store(store_id).await.expect("Failed to open store");
|
||||||
handle.put(b"/key", b"value").await.expect("put failed");
|
handle.put(b"/key", b"value").await.expect("put failed");
|
||||||
assert_eq!(handle.get(b"/key").await.unwrap(), Some(b"value".to_vec()));
|
assert_eq!(handle.get(b"/key").await.unwrap(), Some(b"value".to_vec()));
|
||||||
|
|
||||||
@@ -679,10 +691,10 @@ mod tests {
|
|||||||
let store_a = node.create_store().expect("create A");
|
let store_a = node.create_store().expect("create A");
|
||||||
let store_b = node.create_store().expect("create B");
|
let store_b = node.create_store().expect("create B");
|
||||||
|
|
||||||
let (handle_a, _) = node.open_store(store_a).expect("open A");
|
let (handle_a, _) = node.open_store(store_a).await.expect("open A");
|
||||||
handle_a.put(b"/key", b"from A").await.expect("put A");
|
handle_a.put(b"/key", b"from A").await.expect("put A");
|
||||||
|
|
||||||
let (handle_b, _) = node.open_store(store_b).expect("open B");
|
let (handle_b, _) = node.open_store(store_b).await.expect("open B");
|
||||||
assert_eq!(handle_b.get(b"/key").await.unwrap(), None);
|
assert_eq!(handle_b.get(b"/key").await.unwrap(), None);
|
||||||
|
|
||||||
assert_eq!(handle_a.get(b"/key").await.unwrap(), Some(b"from A".to_vec()));
|
assert_eq!(handle_a.get(b"/key").await.unwrap(), Some(b"from A".to_vec()));
|
||||||
|
|||||||
@@ -109,12 +109,12 @@ async fn handle_sync_request(
|
|||||||
|
|
||||||
// Parse store_id from request
|
// Parse store_id from request
|
||||||
let store_id = Uuid::from_slice(&peer_request.store_id)
|
let store_id = Uuid::from_slice(&peer_request.store_id)
|
||||||
.map_err(|_| "Invalid store_id in SyncRequest".to_string())?;
|
.map_err(|_| format!("Invalid store_id in SyncRequest: {} bytes, expected 16", peer_request.store_id.len()))?;
|
||||||
|
|
||||||
println!("[Sync] Received SyncRequest for store {}", store_id);
|
println!("[Sync] Received SyncRequest for store {}", store_id);
|
||||||
|
|
||||||
// Open the requested store
|
// Open the requested store (uses cache if available)
|
||||||
let (store, _info) = node.open_store(store_id)
|
let (store, _info) = node.open_store(store_id).await
|
||||||
.map_err(|e| format!("Failed to open store {}: {}", store_id, e))?;
|
.map_err(|e| format!("Failed to open store {}: {}", store_id, e))?;
|
||||||
|
|
||||||
println!("[Sync] Received SyncRequest");
|
println!("[Sync] Received SyncRequest");
|
||||||
|
|||||||
Reference in New Issue
Block a user