use super::*;
pub(super) enum StandaloneWriteError<E> {
Refused(StorageError),
Sql(E),
}
pub(super) fn admit_standalone_operation(
pool: &ConnectionPool,
unit_holds_lease: bool,
operation: &'static str,
vacuum: bool,
) -> Result<Option<crate::disk_guard::VolumeLease>, StorageError> {
let admission = pool.write_admission();
let to_storage =
|error: SqliteError| error.into_storage_error(StorageCapability::Sql, operation);
let lease = acquire_standalone_lease(pool, unit_holds_lease, operation)?;
if vacuum {
admission.check_for_vacuum()
} else {
admission.check()
}
.map_err(to_storage)?;
Ok(lease)
}
pub(super) fn acquire_standalone_lease(
pool: &ConnectionPool,
unit_holds_lease: bool,
operation: &'static str,
) -> Result<Option<crate::disk_guard::VolumeLease>, StorageError> {
if unit_holds_lease {
return Ok(None);
}
pool.write_admission()
.acquire()
.map_err(|error| error.into_storage_error(StorageCapability::Sql, operation))
}
pub(super) async fn acquire_unit_lease(
pool: Arc<ConnectionPool>,
) -> khive_storage::types::StorageResult<Option<crate::disk_guard::DetachedVolumeLease>> {
tokio::task::spawn_blocking(move || {
let lease = pool
.write_admission()
.acquire()
.map_err(|error| error.into_storage_error(StorageCapability::Sql, "atomic_unit"))?;
Ok(lease.map(crate::disk_guard::VolumeLease::detach_from_thread))
})
.await
.map_err(|error| StorageError::driver(StorageCapability::Sql, "atomic_unit", error))?
}