Use StorageHandle in tor_circmgr.

This commit is contained in:
Nick Mathewson 2021-09-30 15:27:48 -04:00
parent 37bec4997d
commit f1d6779218
3 changed files with 15 additions and 70 deletions

View File

@ -252,20 +252,20 @@ pub struct CircuitBuilder<R: Runtime> {
path_config: crate::PathConfig,
/// State-manager object to use in storing current state.
#[allow(dead_code)]
storage: crate::state::DynStateMgr,
storage: crate::TimeoutStateHandle,
}
impl<R: Runtime> CircuitBuilder<R> {
/// Construct a new [`CircuitBuilder`].
// TODO: eventually I'd like to make this a public function, but
// DynStateMgr is private.
// TimeoutStateHandle is private.
pub(crate) fn new(
runtime: R,
chanmgr: Arc<ChanMgr<R>>,
path_config: crate::PathConfig,
storage: crate::state::DynStateMgr,
storage: crate::TimeoutStateHandle,
) -> Self {
let timeouts = match storage.load_timeout_data() {
let timeouts = match storage.load() {
Ok(Some(v)) => ParetoTimeoutEstimator::from_state(v),
Ok(None) => ParetoTimeoutEstimator::default(),
Err(e) => {
@ -287,7 +287,8 @@ impl<R: Runtime> CircuitBuilder<R> {
// changed.
let _ignore = self.storage.try_lock()?; // XXXX don't ignore.
let state = self.builder.timeouts.build_state();
self.storage.save_timeout_data(&state)
self.storage.store(&state)?;
Ok(())
}
/// Reconfigure this builder using the latest set of network parameters.

View File

@ -69,7 +69,6 @@ mod err;
mod impls;
mod mgr;
pub mod path;
mod state;
mod timeouts;
mod usage;
@ -86,6 +85,12 @@ use usage::TargetCircUsage;
/// A Result type as returned from this crate.
pub type Result<T> = std::result::Result<T, Error>;
/// Type alias for dynamic StorageHandle that can handle our timeout state.
type TimeoutStateHandle = tor_persist::DynStorageHandle<timeouts::pareto::ParetoTimeoutState>;
/// Key used to load timeout state information.
const PARETO_TIMEOUT_DATA_KEY: &str = "circuit_timeouts";
/// Represents what we know about the Tor network.
///
/// This can either be a complete directory, or a list of fallbacks.
@ -148,12 +153,8 @@ pub struct CircMgr<R: Runtime> {
/// The underlying circuit manager object that implements our behavior.
mgr: Arc<mgr::AbstractCircMgr<build::CircuitBuilder<R>, R>>,
/// A state manager for recording timeout history and guard information.
///
/// (Right now there is only one implementation of CircStateMgr, but I
/// think we'll want to have more before too much time is up. In any
/// case I don't want to parameterize on this type.)
storage: state::DynStateMgr,
/// A handle to the state manager for recording timeout history.
storage: TimeoutStateHandle,
}
impl<R: Runtime> CircMgr<R> {
@ -173,7 +174,7 @@ impl<R: Runtime> CircMgr<R> {
circuit_timing,
} = config;
let storage: state::DynStateMgr = Arc::new(storage);
let storage = storage.create_handle(PARETO_TIMEOUT_DATA_KEY);
let builder =
build::CircuitBuilder::new(runtime.clone(), chanmgr, path_config, Arc::clone(&storage));

View File

@ -1,57 +0,0 @@
//! Code to manage persistence for a circuit manager's state.
//!
//! For now, there's only one kind of data we need to persist across
//! runs: timeout data. Eventually we'll also to persist guard data.
//!
//! Some of the choices here are motivated by another long-term goal:
//! to allow multiple collaborating processes to share data on disk.
use crate::timeouts::pareto::ParetoTimeoutState;
use crate::Result;
use tor_persist::StateMgr;
/// Type alias for an Arc<dyn CircStateMgr>.
pub(crate) type DynStateMgr = std::sync::Arc<dyn CircStateMgr + Send + Sync + 'static>;
/// Crate-local trait, used to represent anything that can store circmgr data.
///
/// We declare a separate trait here, rather than just using
/// `StateMgr`, for two reasons:
/// - We want an interface to StateMgr that gives it more type-safety.
/// - StateMgr isn't object-safe.
pub(crate) trait CircStateMgr {
/// Return true if we're able to store to this state manager.
fn have_lock(&self) -> bool;
/// Try to get the lock on this state manager.
///
/// Returns `Ok(true) if we have the lock, and `Ok(false) if
/// another process has it.
fn try_lock(&self) -> Result<bool>;
/// Try to load our persistent timeout data from storage.
fn load_timeout_data(&self) -> Result<Option<ParetoTimeoutState>>;
/// Replace our persistent timeout data on storage with the data
/// in `state`.
fn save_timeout_data(&self, state: &ParetoTimeoutState) -> Result<()>;
}
/// Key used to load timeout state information.
const PARETO_TIMEOUT_DATA_KEY: &str = "circuit_timeouts";
impl<M: StateMgr> CircStateMgr for M {
fn have_lock(&self) -> bool {
self.can_store()
}
fn try_lock(&self) -> Result<bool> {
Ok(StateMgr::try_lock(self)?)
}
fn load_timeout_data(&self) -> Result<Option<ParetoTimeoutState>> {
Ok(self.load(PARETO_TIMEOUT_DATA_KEY)?)
}
fn save_timeout_data(&self, state: &ParetoTimeoutState) -> Result<()> {
self.store(PARETO_TIMEOUT_DATA_KEY, state)?;
Ok(())
}
}