Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -47,6 +47,21 @@ impl SyncIndexer for ConcurrentRadixTreeCompressed {
}
let _ = resp.send(applied);
}
WorkerTask::ApproximateTtl(task) => task.apply(|event| {
let kind = EventKind::of(&event.event.data);
let result = self.apply_event(&mut lookup, event, counters.as_ref());
let applied = result.is_ok();
if result.is_err() {
tracing::warn!(
"Failed to apply approximate TTL event: {:?}",
result.as_ref().err()
);
}
if let Some(ref counters) = counters {
counters.inc(kind, result);
}
applied
}),
WorkerTask::ApproximateLru(task) => {
approximate_lru.observe_task(&task);
let ApproximateLruTask {
Expand Down Expand Up @@ -116,9 +131,13 @@ impl SyncIndexer for ConcurrentRadixTreeCompressed {
}
WorkerTask::RemoveWorker {
worker_id,
prune_manager,
sweep_tree,
resp,
} => {
if let Some(manager) = prune_manager {
manager.remove_worker(worker_id);
}
approximate_lru.forget_worker(worker_id);
self.erase_worker_coverage(
&mut lookup,
Expand All @@ -130,8 +149,12 @@ impl SyncIndexer for ConcurrentRadixTreeCompressed {
WorkerTask::RemoveWorkerDpRank {
worker_id,
dp_rank,
prune_manager,
sweep_tree,
} => {
if let Some(manager) = prune_manager {
manager.remove_worker_dp_rank(WorkerWithDpRank::new(worker_id, dp_rank));
}
approximate_lru.forget_rank(WorkerWithDpRank::new(worker_id, dp_rank));
self.erase_worker_coverage(
&mut lookup,
Expand Down
63 changes: 60 additions & 3 deletions lib/kv-router/src/indexer/kv_indexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ fn apply_routing_decision_with_prune_tracking(
pm.insert_block_entries(block_entries);
}

fn apply_prune_removes(trie: &mut RadixTree, entries: Vec<BlockEntry>, event_id_counter: &mut u64) {
fn apply_prune_removes(
trie: &mut RadixTree,
entries: Vec<BlockEntry>,
prune_manager: &WorkerPruneManager,
event_id_counter: &mut u64,
) {
let mut entries_by_worker = BTreeMap::<WorkerWithDpRank, Vec<BlockEntry>>::new();
for entry in entries {
entries_by_worker
Expand All @@ -110,7 +115,11 @@ fn apply_prune_removes(trie: &mut RadixTree, entries: Vec<BlockEntry>, event_id_
.push(entry);
}

for (worker, mut entries) in entries_by_worker {
for (worker, entries) in entries_by_worker {
let mut entries = prune_manager.take_pending_expirations(worker, entries);
if entries.is_empty() {
continue;
}
entries.sort_unstable_by_key(|entry| entry.seq_position);
*event_id_counter += 1;
let event = RouterEvent::new(
Expand Down Expand Up @@ -288,7 +297,7 @@ fn drain_pending_mutations(

if let Some(pm) = prune_manager {
let entries = pm.drain_due_and_pending(tokio::time::Instant::now());
apply_prune_removes(trie, entries, event_id_counter);
apply_prune_removes(trie, entries, pm, event_id_counter);
}
}

Expand Down Expand Up @@ -623,6 +632,7 @@ impl KvIndexer {
apply_prune_removes(
&mut trie,
entries,
pm,
&mut event_id_counter,
);
}
Expand Down Expand Up @@ -1082,3 +1092,50 @@ mod fifo_reset_tests {
assert_eq!(new_scores.scores.get(&worker), Some(&1));
}
}

#[cfg(test)]
mod prune_ordering_tests {
use super::*;

#[tokio::test(start_paused = true)]
async fn direct_routing_refresh_invalidates_a_dequeued_expiration() {
let ttl = std::time::Duration::from_secs(10);
let manager = WorkerPruneManager::new(PruneConfig { ttl });
let worker = WorkerWithDpRank::new(7, 0);
let hashes = vec![LocalBlockHash(1)];
let sequence_hashes = crate::protocols::compute_seq_hash_for_block(&hashes);
let mut trie = RadixTree::new();
let mut event_id = 0;
let route = || RoutingDecisionRequest {
worker,
local_hashes: hashes.clone(),
sequence_hashes: sequence_hashes.clone(),
};
apply_routing_decision_with_prune_tracking(
&mut trie,
route(),
&Some(manager.clone()),
&mut event_id,
);
tokio::time::advance(ttl).await;
let expired = manager.drain_due_and_pending(tokio::time::Instant::now());
assert_eq!(expired.len(), 1);
apply_routing_decision_with_prune_tracking(
&mut trie,
route(),
&Some(manager.clone()),
&mut event_id,
);
apply_prune_removes(&mut trie, expired, &manager, &mut event_id);
assert_eq!(
trie.find_matches(hashes.clone(), false).scores.get(&worker),
Some(&1)
);

tokio::time::advance(ttl).await;
let expired = manager.drain_due_and_pending(tokio::time::Instant::now());
apply_prune_removes(&mut trie, expired, &manager, &mut event_id);
assert!(trie.find_matches(hashes, false).scores.is_empty());
manager.shutdown();
}
}
31 changes: 29 additions & 2 deletions lib/kv-router/src/indexer/lower_tier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,21 @@ impl SyncIndexer for LowerTierIndexer {
}
let _ = resp.send(applied);
}
WorkerTask::ApproximateTtl(task) => task.apply(|event| {
let kind = EventKind::of(&event.event.data);
let result = self.apply_event(&mut worker_blocks, event);
let applied = result.is_ok();
if result.is_err() {
tracing::warn!(
"Failed to apply approximate TTL event: {:?}",
result.as_ref().err()
);
}
if let Some(ref counters) = counters {
counters.inc(kind, result);
}
applied
}),
WorkerTask::ApproximateLru(task) => task.complete(Err(KvRouterError::Unsupported(
"approximate LRU is not supported for lower-tier indexers".to_string(),
))),
Expand Down Expand Up @@ -1096,14 +1111,26 @@ impl SyncIndexer for LowerTierIndexer {
}
}
WorkerTask::RemoveWorker {
worker_id, resp, ..
worker_id,
prune_manager,
resp,
..
} => {
if let Some(manager) = prune_manager {
manager.remove_worker(worker_id);
}
self.remove_worker(&mut worker_blocks, worker_id);
let _ = resp.send(());
}
WorkerTask::RemoveWorkerDpRank {
worker_id, dp_rank, ..
worker_id,
dp_rank,
prune_manager,
..
} => {
if let Some(manager) = prune_manager {
manager.remove_worker_dp_rank(WorkerWithDpRank::new(worker_id, dp_rank));
}
self.remove_worker_dp_rank(&mut worker_blocks, worker_id, dp_rank);
}
WorkerTask::DumpEvents(sender) => {
Expand Down
31 changes: 29 additions & 2 deletions lib/kv-router/src/indexer/positional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,21 @@ impl SyncIndexer for PositionalIndexer {
}
let _ = resp.send(applied);
}
WorkerTask::ApproximateTtl(task) => task.apply(|event| {
let kind = EventKind::of(&event.event.data);
let result = self.apply_event(&mut worker_blocks, event, counters.as_ref());
let applied = result.is_ok();
if result.is_err() {
tracing::warn!(
"Failed to apply approximate TTL event: {:?}",
result.as_ref().err()
);
}
if let Some(ref counters) = counters {
counters.inc(kind, result);
}
applied
}),
WorkerTask::ApproximateLru(task) => task.complete(Err(KvRouterError::Unsupported(
"approximate LRU requires ConcurrentRadixTreeCompressed".to_string(),
))),
Expand Down Expand Up @@ -285,14 +300,26 @@ impl SyncIndexer for PositionalIndexer {
}
}
WorkerTask::RemoveWorker {
worker_id, resp, ..
worker_id,
prune_manager,
resp,
..
} => {
if let Some(manager) = prune_manager {
manager.remove_worker(worker_id);
}
self.remove_worker_blocks_impl(&mut worker_blocks, worker_id);
let _ = resp.send(());
}
WorkerTask::RemoveWorkerDpRank {
worker_id, dp_rank, ..
worker_id,
dp_rank,
prune_manager,
..
} => {
if let Some(manager) = prune_manager {
manager.remove_worker_dp_rank(WorkerWithDpRank::new(worker_id, dp_rank));
}
self.remove_worker_dp_rank_impl(&mut worker_blocks, worker_id, dp_rank);
}
WorkerTask::CleanupStaleChildren => {
Expand Down
Loading
Loading