Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ struct InjectedActivationFaultsV1 {
publication_deadlines: std::collections::BTreeSet<String>,
terminal_failures: std::collections::BTreeSet<String>,
gates: std::collections::BTreeMap<String, Arc<InjectedActivationGateStateV1>>,
/// CPU time the memory activation spends beside its prewarm, standing in
/// for a prewarm that runs long on a loaded host.
prewarm_cpu: std::collections::BTreeMap<String, std::time::Duration>,
catalog_warm_gates: std::collections::BTreeMap<String, Arc<InjectedActivationGateStateV1>>,
}

Expand Down Expand Up @@ -178,13 +175,6 @@ pub fn injected_activation_attempt_count(worktree_id: &WorktreeId) -> usize {
.unwrap_or(0)
}

#[cfg(test)]
pub fn set_injected_activation_prewarm_cpu(worktree_id: &WorktreeId, cpu: std::time::Duration) {
injected_faults()
.prewarm_cpu
.insert(worktree_id.as_str().to_owned(), cpu);
}

#[cfg(test)]
pub fn set_injected_resident_memory_refusal(worktree_id: &WorktreeId, refused: bool) {
set_injected_flag(
Expand Down Expand Up @@ -643,22 +633,13 @@ impl CodeGraphActivationAuthorityV1 {
),
));
}
let prewarm_cpu = injected_faults().prewarm_cpu.remove(worktree_id.as_str());
native_runtime::spawn_blocking(move || {
if let Some(cpu) = prewarm_cpu {
let spun = std::time::Instant::now();
while spun.elapsed() < cpu {
std::hint::spin_loop();
}
}
latest.prewarm_serving_derivations();
})
.await
.map_err(|error| {
CodeIndexSchedulerErrorV1::GraphActivation(format!(
"code graph activation task failed: {error}"
))
})?;
native_runtime::spawn_blocking(move || latest.prewarm_serving_derivations())
.await
.map_err(|error| {
CodeIndexSchedulerErrorV1::GraphActivation(format!(
"code graph activation task failed: {error}"
))
})?;
Ok(None)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2093,38 +2093,3 @@ async fn readers_of_a_build_waiting_for_memory_do_not_spin_the_worker() {

registry.shutdown().await;
}

/// A memory activation whose prewarm outlasts the CPU one native poll may
/// spend still seats the generation a reader demanded. The prewarm is
/// synchronous: run inside the worker's poll, the debug long-poll guard fails
/// the worker and the seat never arrives (#4016).
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn a_memory_activation_longer_than_one_native_poll_still_seats() {
let fixture = GitFixture::new(ALPHA_LIB_V1);
let store = TempDir::new().expect("store root");
let registry = CodeIndexSchedulerRegistryV1::with_background_reconcile_permits(1, 1);
let first_pass = registry
.background_reconcile_admission()
.acquire_owned()
.await
.expect("hold the worker before its first activation");
registry
.mount_worktree(
test_project_id(),
fixture.path(),
store.path().to_path_buf(),
)
.await
.expect("mount");
let scope = registry
.serving_code_scope(fixture.path())
.await
.expect("mounted scope");
super::super::graph_activation::set_injected_activation_prewarm_cpu(
&scope.worktree_id,
tracedecay_runtime_core::native_runtime::LONG_POLL_CPU * 4,
);
drop(first_pass);
wait_for_live_complete_generation(&registry, fixture.path()).await;
registry.shutdown().await;
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,6 @@ pub(super) struct RegisteredSchemaConvergenceMaintenance {
execution_count: Arc<std::sync::atomic::AtomicUsize>,
#[cfg(any(test, feature = "test-helpers"))]
gate: StdMutex<Option<Arc<RegisteredSchemaConvergenceTestGateState>>>,
/// CPU time spent beside the allocator trim, standing in for a trim of
/// a large heap.
#[cfg(any(test, feature = "test-helpers"))]
trim_cpu: StdMutex<Option<std::time::Duration>>,
}

enum SchemaConvergenceTarget {
Expand Down Expand Up @@ -183,8 +179,6 @@ impl RegisteredSchemaConvergenceMaintenance {
execution_count: Arc::new(std::sync::atomic::AtomicUsize::new(0)),
#[cfg(any(test, feature = "test-helpers"))]
gate: StdMutex::new(None),
#[cfg(any(test, feature = "test-helpers"))]
trim_cpu: StdMutex::new(None),
}
}

Expand Down Expand Up @@ -317,11 +311,6 @@ impl RegisteredSchemaConvergenceMaintenance {
.lock()
.expect("registered schema convergence test gate lock remains healthy")
.clone();
#[cfg(any(test, feature = "test-helpers"))]
let trim_cpu = *self
.trim_cpu
.lock()
.expect("registered schema convergence trim cost lock remains healthy");
let statuses = Arc::clone(&self.statuses);
let foreground_project_opens = Arc::clone(&self.foreground_project_opens);
let concurrency = Arc::clone(&self.concurrency);
Expand Down Expand Up @@ -372,17 +361,7 @@ impl RegisteredSchemaConvergenceMaintenance {
}
// `malloc_trim` walks every glibc arena: up to 0.8 s of CPU on a
// large heap, which would stall this native worker's I/O.
let _ = native_runtime::spawn_blocking(move || {
#[cfg(any(test, feature = "test-helpers"))]
if let Some(cpu) = trim_cpu {
let spun = std::time::Instant::now();
while spun.elapsed() < cpu {
std::hint::spin_loop();
}
}
release_process_allocator_memory_v1()
})
.await;
let _ = native_runtime::spawn_blocking(release_process_allocator_memory_v1).await;
drop(permit);
let status = match result {
Ok(()) => {
Expand Down Expand Up @@ -507,14 +486,6 @@ impl RegisteredSchemaConvergenceMaintenance {
}
}

#[cfg(any(test, feature = "test-helpers"))]
pub(super) fn inject_trim_cpu(&self, cpu: std::time::Duration) {
*self
.trim_cpu
.lock()
.expect("registered schema convergence trim cost lock remains healthy") = Some(cpu);
}

#[cfg(any(test, feature = "test-helpers"))]
pub(super) fn install_gate(&self) -> RegisteredSchemaConvergenceTestGate {
let state = Arc::new(RegisteredSchemaConvergenceTestGateState {
Expand Down Expand Up @@ -783,11 +754,6 @@ impl DaemonSessionRuntimeRegistryV1 {
self.registered_schema_convergence.install_gate()
}

#[cfg(any(test, feature = "test-helpers"))]
pub fn inject_registered_schema_convergence_trim_cpu_for_test(&self, cpu: std::time::Duration) {
self.registered_schema_convergence.inject_trim_cpu(cpu);
}

#[cfg(any(test, feature = "test-helpers"))]
pub fn registered_schema_convergence_schedule_count_for_test(&self) -> usize {
self.registered_schema_convergence
Expand Down
38 changes: 0 additions & 38 deletions crates/tracedecay/src/daemon/store_runtime_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1349,44 +1349,6 @@ async fn schema_convergence_is_reported_and_completes_after_admission() {
);
}

/// Convergence ends with a glibc `malloc_trim`, which walks every arena and
/// measured up to 0.8 s of CPU in a loaded test process. Run inside the
/// convergence task's poll, it stalls every socket wake on that native worker,
/// and the debug long-poll guard fails the task as it completes (#4023).
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn schema_convergence_completes_when_its_allocator_trim_outlasts_a_native_poll() {
let (_temporary, identity, project_id, project_root, _sessions_path, _database_scope) =
project_sessions_pending_convergence("project.schema-long-trim").await;
let shard_id = StoreShardIdV1::project_sessions(
identity.brain_id().clone(),
identity.profile_id().clone(),
project_id.clone(),
);
let registry = DaemonSessionRuntimeRegistryV1::open_with_session_maintenance(identity, true)
.await
.expect("session runtime registry");
registry.inject_registered_schema_convergence_trim_cpu_for_test(
tracedecay_runtime_core::native_runtime::LONG_POLL_CPU * 4,
);

registry
.project_sessions(project_id, [project_root])
.await
.expect("project sessions admission");

assert_eq!(
wait_for_schema_convergence(&registry, &shard_id).await,
RegisteredSchemaConvergenceStatus::Complete
);
tokio::time::timeout(
MUST_NOT_BLOCK,
registry.shutdown_terminal_tasks(&tracedecay_runtime_core::native_runtime::cx().unwrap()),
)
.await
.expect("terminal shutdown joins the finished convergence task")
.expect("the convergence task must finish without failing");
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn foreground_project_open_defers_historical_convergence_until_full_publication() {
let (_temporary, identity, project_id, project_root, _sessions_path, _database_scope) =
Expand Down
Loading