The commit phase (Phase 3) of the two-phase settings broadcast is fully implemented. This includes: - Settings version increment in task store - Per-node version advancement in node_settings_version table - X-Miroir-Settings-Version header stamping on search responses - Broadcast completion and in-flight state clearing All tests pass and the implementation follows plan §13.5. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
5 KiB
5 KiB
P5.5.c: Commit Phase Implementation - Settings Version Increment
Bead: miroir-uhj.5.3 Date: 2026-05-23 Plan Reference: §13.5 Two-phase settings broadcast with verification
Summary
The commit phase (Phase 3) of the two-phase settings broadcast is already fully implemented in the codebase. This phase is the critical moment where:
- The cluster-wide
settings_versionis incremented in the task store - All verified nodes have their
node_settings_versionadvanced - Future responses include the
X-Miroir-Settings-Versionheader - New writes are allowed to proceed freely (broadcast completes)
Implementation Details
1. Core Commit Logic
File: crates/miroir-core/src/settings.rs:228-269
pub async fn commit(&self, index: &str) -> Result<u64> {
// Increment global settings version
let mut version = self.settings_version.write().await;
*version += 1;
let new_version = *version;
// Update per-node versions for all nodes that verified successfully
let mut node_versions = self.node_settings_version.write().await;
let now = now_ms();
for node_id in status.node_hashes.keys() {
node_versions.insert((index.to_string(), node_id.clone()), new_version);
// Persist to task store
if let Some(ref store) = self.task_store {
let _ = store.upsert_node_settings_version(
index,
node_id,
new_version as i64,
now,
);
}
}
status.phase = BroadcastPhase::Commit;
status.settings_version = Some(new_version);
Ok(new_version)
}
2. Integration in Proxy Layer
File: crates/miroir-proxy/src/routes/indexes.rs:1071-1093
The commit phase is called after successful verification:
// Phase 3: Commit - increment settings version
let new_version = state.settings_broadcast.commit(index).await?;
// Update settings version metric
state.metrics.set_settings_version(index, new_version);
state.metrics.clear_settings_broadcast_phase(index);
// Complete and remove from in-flight tracking
state.settings_broadcast.complete(index).await.ok();
3. Header Stamping
File: crates/miroir-proxy/src/routes/search.rs
The X-Miroir-Settings-Version header is stamped on search responses:
Single search (lines 489-492):
let current_version = state.settings_broadcast.current_version().await;
if current_version > 0 {
response = response.header("X-Miroir-Settings-Version", current_version.to_string());
}
Multi-target search (lines 836-838):
let current_version = state.settings_broadcast.current_version().await;
if current_version > 0 {
response = response.header("X-Miroir-Settings-Version", current_version.to_string());
}
4. Per-Node Version Persistence
Schema: node_settings_version table
CREATE TABLE IF NOT EXISTS node_settings_version (
index_uid TEXT NOT NULL,
node_id TEXT NOT NULL,
version INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
PRIMARY KEY (index_uid, node_id)
);
Task Store Operations:
upsert_node_settings_version(index_uid, node_id, version, updated_at)- Persist per-node versionget_node_settings_version(index_uid, node_id)- Retrieve for X-Miroir-Min-Settings-Version checks
Phase 3 Flow
- Increment global version:
settings_versionis incremented atomically - Advance per-node versions: Each node that verified successfully gets its version advanced
- Persist to task store:
node_settings_versiontable is updated for all (index, node) pairs - Stamp responses: Future search responses include
X-Miroir-Settings-Versionheader - Clear in-flight state: Broadcast is removed from in-flight tracking
- Allow new writes: Subsequent settings updates can proceed
Client Behavior
Clients can observe the new settings version via:
- Response header:
X-Miroir-Settings-Versionon search responses - Freshness floor: Echo back as
X-Miroir-Min-Settings-Versionfor session-consistent reads - Staleness detection: Nodes with
node_settings_version < floorare excluded from covering set
Metrics
miroir_settings_version(gauge): Increments only on successful commitmiroir_settings_broadcast_phase(gauge): Cleared after commit
Testing
All tests pass:
test_two_phase_settings_broadcast_normal_flow- ✅ Verifies version incrementtest_node_settings_version_tracking_multiple_updates- ✅ Verifies per-node trackingtest_settings_version_persistence_to_task_store- ✅ Verifies persistence
References
- Plan §13.5:
/home/coding/miroir/docs/plan/plan.md - Core implementation:
/home/coding/miroir/crates/miroir-core/src/settings.rs:228-269 - Proxy integration:
/home/coding/miroir/crates/miroir-proxy/src/routes/indexes.rs:1071-1093 - Header stamping:
/home/coding/miroir/crates/miroir-proxy/src/routes/search.rs:489-492,836-838 - Tests:
/home/coding/miroir/crates/miroir-proxy/tests/p5_5_two_phase_settings_broadcast.rs