Merged 10 upstream commits (MemTable, read-your-writes tests, feed endpoint, security hardening, signed assertions, source registry, dashboard enhancements) and fixed all test failures across the full workspace (2656/2656 passing). Key fixes: - fix(cluster): DashMap deadlock in swim.rs suspect_node/fail_node/alive_node - DashMap::get_mut RefMut + iter() on same map = non-reentrant write lock deadlock - Fix: extract clone in scoped block to drop RefMut before calling update_node_gauges() - 6 previously-hanging SWIM tests now pass in <2s - fix(sim): replace background-task+polling ingestion with synchronous process_pending() - smoke_high_volume_simulation was CPU-starved under 2656 parallel tests - Removed ingestor.start() + wait_until_ingested() pattern throughout sim - All arena functions now call ingestor.process_pending() directly (deterministic) - fix(test): v2 signature helper used wrong hash (rkyv vs canonical compute_content_hash_v2) - fix(test): quota test signed "test" but v1 requires "subject:predicate" format - fix(test): http_validation now accepts 400 for valid-format-but-invalid-crypto hex - fix(test): scale_adaptive micro tier assertions updated (auto_promote upstream change) - config: add nextest.toml with slow-timeout for background-task-tests group Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
45 lines
1.6 KiB
Rust
45 lines
1.6 KiB
Rust
//! Storage orchestration for IngestWorker.
|
|
|
|
use super::IngestWorker;
|
|
use crate::error::Result;
|
|
use stemedb_storage::KVStore;
|
|
|
|
impl<S: KVStore + 'static> IngestWorker<S> {
|
|
/// Write cascade markers for superseded epochs.
|
|
///
|
|
/// Walks the epoch supersession chain and writes markers so that
|
|
/// queries can check if an epoch is superseded in O(1) time.
|
|
pub async fn write_supersession_cascade(
|
|
&self,
|
|
new_epoch_id: &[u8; 32],
|
|
old_epoch_id: &[u8; 32],
|
|
) -> Result<()> {
|
|
let mut current_id = *old_epoch_id;
|
|
let mut depth = 0;
|
|
const MAX_CASCADE_DEPTH: usize = 100;
|
|
|
|
while depth < MAX_CASCADE_DEPTH {
|
|
// Write marker: \x00SUPERSEDED:{old_id} -> {new_id}
|
|
let key = stemedb_storage::key_codec::superseded_key(&hex::encode(current_id));
|
|
self.store.put(&key, new_epoch_id).await?;
|
|
|
|
// Follow the chain: look up what this epoch superseded
|
|
let epoch_key = stemedb_storage::key_codec::epoch_key(&hex::encode(current_id));
|
|
if let Some(bytes) = self.store.get(&epoch_key).await? {
|
|
let epoch: stemedb_core::types::Epoch = stemedb_core::serde::deserialize(&bytes)
|
|
.map_err(|e| crate::error::IngestError::Serialization(e.to_string()))?;
|
|
|
|
if let Some(prev_id) = epoch.supersedes {
|
|
current_id = prev_id;
|
|
depth += 1;
|
|
} else {
|
|
break;
|
|
}
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|