use std::net::SocketAddr;
use nodedb_cluster::calvin::types::ReleaseReason;
use crate::control::state::SharedState;
use super::store::SessionStore;
pub(super) async fn release_session_reservations(
state: &SharedState,
sessions: &SessionStore,
addr: &SocketAddr,
reason: ReleaseReason,
) {
let (owner, vshards) = sessions.take_reservations(addr);
let Some(owner) = owner else { return };
for vshard in vshards {
let _ = crate::control::planner::calvin::reservation::release_reservation(
state, owner, vshard, reason,
)
.await;
}
}
pub(super) async fn release_and_rollback(
state: &SharedState,
sessions: &SessionStore,
addr: &SocketAddr,
) {
release_session_reservations(state, sessions, addr, ReleaseReason::Abort).await;
rollback_with_gap_free(sessions, addr, state);
}
fn rollback_with_gap_free(sessions: &SessionStore, addr: &SocketAddr, state: &SharedState) {
if let Ok(reservations) = sessions.rollback(addr) {
for handle in &reservations {
let key = handle.sequence_key.clone();
let registry = &state.sequence_registry;
registry.gap_free_manager().rollback(handle, || {
let map = registry.sequences_read();
if let Some(h) = map.get(&key) {
h.rollback_one();
}
});
}
}
}