refactor: split pod metadata store
This commit is contained in:
@@ -16,12 +16,15 @@ use llm_worker::Worker;
|
||||
use llm_worker::llm_client::event::{Event as LlmEvent, ResponseStatus, StatusEvent};
|
||||
use llm_worker::llm_client::types::Item;
|
||||
use llm_worker::llm_client::{ClientError, LlmClient, Request};
|
||||
use pod_store::{CombinedStore, FsPodStore, PodMetadataStore};
|
||||
use protocol::{Event, Method, RunResult};
|
||||
use session_store::{FsStore, LogEntry, PodMetadataStore, Store};
|
||||
use session_store::{FsStore, LogEntry, Store};
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
use pod::{Pod, PodController};
|
||||
|
||||
type TestStore = CombinedStore<FsStore, FsPodStore>;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct MockClient {
|
||||
responses: Arc<Vec<Vec<LlmEvent>>>,
|
||||
@@ -145,11 +148,14 @@ permission = "write"
|
||||
async fn make_pod_with_manifest(
|
||||
manifest_toml: &str,
|
||||
client: MockClient,
|
||||
) -> Pod<MockClient, FsStore> {
|
||||
) -> Pod<MockClient, TestStore> {
|
||||
let manifest = pod::PodManifest::from_toml(manifest_toml).unwrap();
|
||||
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
std::mem::forget(store_tmp);
|
||||
|
||||
let pwd_tmp = tempfile::tempdir().unwrap();
|
||||
@@ -163,7 +169,7 @@ async fn make_pod_with_manifest(
|
||||
pod
|
||||
}
|
||||
|
||||
async fn make_pod(client: MockClient) -> Pod<MockClient, FsStore> {
|
||||
async fn make_pod(client: MockClient) -> Pod<MockClient, TestStore> {
|
||||
make_pod_with_manifest(POST_RUN_MANIFEST_TOML, client).await
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,10 @@ use llm_worker::llm_client::{ClientError, LlmClient, Request};
|
||||
use memory::WorkspaceLayout;
|
||||
use memory::extract::{ExtractedPayload, write_staging};
|
||||
use memory::schema::SourceRef;
|
||||
use pod_store::{CombinedStore, FsPodStore};
|
||||
use session_store::FsStore;
|
||||
|
||||
type TestStore = CombinedStore<FsStore, FsPodStore>;
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
use pod::{Event, Pod};
|
||||
@@ -155,11 +158,14 @@ async fn make_pod_with(
|
||||
manifest_toml: &str,
|
||||
pwd: std::path::PathBuf,
|
||||
client: MockClient,
|
||||
) -> Pod<MockClient, FsStore> {
|
||||
) -> Pod<MockClient, TestStore> {
|
||||
let manifest = pod::PodManifest::from_toml(manifest_toml).unwrap();
|
||||
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
std::mem::forget(store_tmp);
|
||||
|
||||
let scope = pod::Scope::writable(&pwd).unwrap();
|
||||
@@ -184,7 +190,7 @@ fn write_n_staging(layout: &WorkspaceLayout, n: usize) -> Vec<uuid::Uuid> {
|
||||
ids
|
||||
}
|
||||
|
||||
fn attach_event_receiver(pod: &mut Pod<MockClient, FsStore>) -> broadcast::Receiver<Event> {
|
||||
fn attach_event_receiver(pod: &mut Pod<MockClient, TestStore>) -> broadcast::Receiver<Event> {
|
||||
let (tx, rx) = broadcast::channel(16);
|
||||
pod.attach_event_tx(tx);
|
||||
rx
|
||||
|
||||
@@ -9,10 +9,13 @@ use llm_worker::llm_client::event::{Event as LlmEvent, ResponseStatus, StatusEve
|
||||
use llm_worker::llm_client::types::Item;
|
||||
use llm_worker::llm_client::{ClientError, LlmClient, Request};
|
||||
use llm_worker::tool::{Tool, ToolDefinition, ToolError, ToolMeta, ToolOutput};
|
||||
use pod_store::{CombinedStore, FsPodStore};
|
||||
use session_store::{FsStore, LogEntry};
|
||||
|
||||
use pod::{Event, Method, Pod, PodController, PodHandle, PodManifest, PodStatus};
|
||||
|
||||
type TestStore = CombinedStore<FsStore, FsPodStore>;
|
||||
|
||||
/// Reconstruct a worker-history-like `Vec<Item>` from the live session
|
||||
/// log mirror held by the Pod's broadcast sink. Replaces the previous
|
||||
/// `PodSharedState.history()` test helper now that the mirror lives in
|
||||
@@ -152,21 +155,24 @@ target = "./"
|
||||
permission = "write"
|
||||
"#;
|
||||
|
||||
async fn make_pod(client: MockClient) -> Pod<MockClient, FsStore> {
|
||||
async fn make_pod(client: MockClient) -> Pod<MockClient, TestStore> {
|
||||
make_pod_with_pwd(client).await.0
|
||||
}
|
||||
|
||||
async fn make_pod_with_pwd(client: MockClient) -> (Pod<MockClient, FsStore>, std::path::PathBuf) {
|
||||
async fn make_pod_with_pwd(client: MockClient) -> (Pod<MockClient, TestStore>, std::path::PathBuf) {
|
||||
make_pod_with_pwd_and_manifest(client, MANIFEST_TOML).await
|
||||
}
|
||||
|
||||
async fn make_pod_with_pwd_and_manifest(
|
||||
client: MockClient,
|
||||
manifest_toml: &str,
|
||||
) -> (Pod<MockClient, FsStore>, std::path::PathBuf) {
|
||||
) -> (Pod<MockClient, TestStore>, std::path::PathBuf) {
|
||||
let manifest = PodManifest::from_toml(manifest_toml).unwrap();
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
std::mem::forget(store_tmp);
|
||||
|
||||
// Separate tempdir to serve as the Pod's pwd/scope — these tests
|
||||
@@ -184,7 +190,7 @@ async fn make_pod_with_pwd_and_manifest(
|
||||
(pod, pwd)
|
||||
}
|
||||
|
||||
async fn spawn_controller(pod: Pod<MockClient, FsStore>) -> PodHandle {
|
||||
async fn spawn_controller(pod: Pod<MockClient, TestStore>) -> PodHandle {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let runtime_base = tmp.path().to_owned();
|
||||
std::mem::forget(tmp);
|
||||
|
||||
@@ -20,10 +20,11 @@ use pod::spawn::comm_tools::{
|
||||
list_pods_tool, read_pod_output_tool, send_to_pod_tool, stop_pod_tool,
|
||||
};
|
||||
use pod::spawn::registry::SpawnedPodRegistry;
|
||||
use pod_store::{CombinedStore, FsPodStore, PodMetadataStore};
|
||||
use protocol::stream::{JsonLineReader, JsonLineWriter};
|
||||
use protocol::{ErrorCode, Event, Greeting, Method};
|
||||
use serde_json::json;
|
||||
use session_store::{FsStore, PodMetadataStore};
|
||||
use session_store::FsStore;
|
||||
use tempfile::TempDir;
|
||||
use tokio::net::UnixListener;
|
||||
use tokio::sync::mpsc;
|
||||
@@ -385,7 +386,10 @@ async fn stop_pod_sends_shutdown_and_releases_scope() {
|
||||
let _env = EnvGuard::acquire();
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let store_tmp = TempDir::new().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
let rd = Arc::new(RuntimeDir::create(tmp.path(), "spawner").await.unwrap());
|
||||
let parent_scope = SharedScope::new(
|
||||
Scope::writable(tmp.path())
|
||||
@@ -512,7 +516,10 @@ async fn restored_registry_uses_pod_state_without_runtime_file() {
|
||||
let _env = EnvGuard::acquire();
|
||||
let runtime_tmp = TempDir::new().unwrap();
|
||||
let store_tmp = TempDir::new().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
unsafe {
|
||||
std::env::set_var("INSOMNIA_RUNTIME_DIR", runtime_tmp.path());
|
||||
}
|
||||
@@ -582,7 +589,10 @@ async fn restored_registry_uses_pod_state_without_runtime_file() {
|
||||
async fn load_from_pod_state_prunes_runtime_children_but_preserves_durable_state() {
|
||||
let runtime_tmp = TempDir::new().unwrap();
|
||||
let store_tmp = TempDir::new().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
let rd = Arc::new(
|
||||
RuntimeDir::create(runtime_tmp.path(), "spawner")
|
||||
.await
|
||||
@@ -635,7 +645,10 @@ async fn load_from_pod_state_reclaims_pruned_child_scope_without_deleting_pod_st
|
||||
let _env = EnvGuard::acquire();
|
||||
let runtime_tmp = TempDir::new().unwrap();
|
||||
let store_tmp = TempDir::new().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
unsafe {
|
||||
std::env::set_var("INSOMNIA_RUNTIME_DIR", runtime_tmp.path());
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
use std::sync::{LazyLock, Mutex};
|
||||
|
||||
use pod::{Pod, PodError};
|
||||
use session_store::{FsStore, PodActiveSegmentRef, PodMetadata, PodMetadataStore, StoreError};
|
||||
use pod_store::{CombinedStore, FsPodStore, PodActiveSegmentRef, PodMetadata, PodMetadataStore};
|
||||
use session_store::{FsStore, StoreError};
|
||||
|
||||
const MINIMAL_MANIFEST_TOML: &str = r#"
|
||||
[pod]
|
||||
@@ -36,7 +37,10 @@ async fn restore_from_pod_metadata_rejects_missing_metadata() {
|
||||
let _lock = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
let manifest = pod::PodManifest::from_toml(MINIMAL_MANIFEST_TOML).unwrap();
|
||||
|
||||
let result = Pod::restore_from_pod_metadata(
|
||||
@@ -59,7 +63,10 @@ async fn restore_from_pod_metadata_rejects_pending_segment() {
|
||||
let _lock = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
let manifest = pod::PodManifest::from_toml(MINIMAL_MANIFEST_TOML).unwrap();
|
||||
let session_id = session_store::new_session_id();
|
||||
store
|
||||
@@ -95,7 +102,10 @@ async fn restore_from_pod_metadata_resolves_active_pointer_through_session_log()
|
||||
let _lock = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
let manifest = pod::PodManifest::from_toml(MINIMAL_MANIFEST_TOML).unwrap();
|
||||
let session_id = session_store::new_session_id();
|
||||
let segment_id = session_store::new_segment_id();
|
||||
@@ -126,7 +136,10 @@ async fn restore_from_manifest_rejects_unknown_segment() {
|
||||
let _lock = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
let manifest = pod::PodManifest::from_toml(MINIMAL_MANIFEST_TOML).unwrap();
|
||||
|
||||
// A freshly-minted id with no jsonl file at all → store returns
|
||||
@@ -155,7 +168,10 @@ async fn restore_from_manifest_rejects_empty_segment_log() {
|
||||
let _lock = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
let manifest = pod::PodManifest::from_toml(MINIMAL_MANIFEST_TOML).unwrap();
|
||||
|
||||
// Pre-create an empty `<sid>/<segid>.jsonl` so `read_all` succeeds
|
||||
@@ -189,7 +205,10 @@ async fn restore_from_manifest_rejects_segment_without_scope_snapshot() {
|
||||
let _lock = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
let manifest = pod::PodManifest::from_toml(MINIMAL_MANIFEST_TOML).unwrap();
|
||||
|
||||
let sid = session_store::new_session_id();
|
||||
|
||||
@@ -25,11 +25,14 @@ use llm_worker::Worker;
|
||||
use llm_worker::llm_client::event::{Event as LlmEvent, ResponseStatus, StatusEvent, UsageEvent};
|
||||
use llm_worker::llm_client::{ClientError, LlmClient, Request};
|
||||
use llm_worker::tool::{Tool, ToolDefinition, ToolError, ToolMeta, ToolOutput};
|
||||
use pod_store::{CombinedStore, FsPodStore};
|
||||
use session_metrics::{DOMAIN, Metric, metrics_from_extensions};
|
||||
use session_store::{FsStore, LogEntry, SegmentId, SessionId, Store, StoreError, TraceEntry};
|
||||
|
||||
use pod::{Pod, PodManifest};
|
||||
|
||||
type TestStore = CombinedStore<FsStore, FsPodStore>;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct MockClient {
|
||||
responses: Arc<Vec<Vec<LlmEvent>>>,
|
||||
@@ -166,13 +169,16 @@ async fn make_pod(
|
||||
client: MockClient,
|
||||
tool_name: &'static str,
|
||||
) -> (
|
||||
Pod<MockClient, FsStore>,
|
||||
Pod<MockClient, TestStore>,
|
||||
tempfile::TempDir,
|
||||
tempfile::TempDir,
|
||||
) {
|
||||
let manifest = PodManifest::from_toml(&manifest_toml).unwrap();
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
let pwd_tmp = tempfile::tempdir().unwrap();
|
||||
let pwd = pwd_tmp.path().to_path_buf();
|
||||
let scope = pod::Scope::writable(&pwd).unwrap();
|
||||
@@ -500,7 +506,10 @@ permission = "write"
|
||||
let client = MockClient::new(vec![text_response_with_cache("hi", 0, 0)]);
|
||||
let manifest = PodManifest::from_toml(manifest_toml).unwrap();
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
let pwd_tmp = tempfile::tempdir().unwrap();
|
||||
let pwd = pwd_tmp.path().to_path_buf();
|
||||
let scope = pod::Scope::writable(&pwd).unwrap();
|
||||
|
||||
@@ -8,10 +8,13 @@ use futures::Stream;
|
||||
use llm_worker::Worker;
|
||||
use llm_worker::llm_client::event::{Event as LlmEvent, ResponseStatus, StatusEvent};
|
||||
use llm_worker::llm_client::{ClientError, LlmClient, Request};
|
||||
use pod_store::{CombinedStore, FsPodStore};
|
||||
use session_store::{FsStore, LogEntry, Store};
|
||||
|
||||
use pod::{Pod, PodError, PromptLoader, SystemPromptTemplate};
|
||||
|
||||
type TestStore = CombinedStore<FsStore, FsPodStore>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Mock LLM Client
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -99,11 +102,14 @@ permission = "write"
|
||||
async fn make_pod_with_body(
|
||||
body: &str,
|
||||
client: MockClient,
|
||||
) -> Result<(Pod<MockClient, FsStore>, PathBuf), PodError> {
|
||||
) -> Result<(Pod<MockClient, TestStore>, PathBuf), PodError> {
|
||||
let manifest = pod::PodManifest::from_toml(MINIMAL_MANIFEST_TOML).unwrap();
|
||||
|
||||
let store_tmp = tempfile::tempdir().unwrap();
|
||||
let store = FsStore::new(store_tmp.path()).unwrap();
|
||||
let store = CombinedStore::new(
|
||||
FsStore::new(store_tmp.path()).unwrap(),
|
||||
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
|
||||
);
|
||||
std::mem::forget(store_tmp);
|
||||
|
||||
let pwd_tmp = tempfile::tempdir().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user