Files
inbuxa-server/crates/store/src/backend/foundationdb/mod.rs
T
jcoffey-dev 3a272096c0
trivy / Check (pull_request) Waiting to run
Import upstream v0.16.23, stripped
Upstream commit: 9d1c75ab68435e4417337f768291e5f947686203
Enterprise-only files removed or emptied: 63
Enterprise-only snippets removed: 118 in 50 files
Dangling module declarations removed: 5
Edits turning enterprise off: 25
Third-party code: 14 files, 0 not in THIRD-PARTY.md
Verification: clean

One snippet more than v0.16.22, in crates/common/src/auth/authentication.rs
(3, was 2).
2026-09-22 16:31:25 -07:00

115 lines
2.6 KiB
Rust

/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use foundationdb::{Database, FdbError};
use std::{
sync::atomic::{AtomicBool, AtomicI64, AtomicU64, Ordering},
time::{Duration, Instant},
};
pub mod blob;
pub mod main;
pub mod read;
pub mod write;
const MAX_VALUE_SIZE: usize = 100000;
const REFRESH_READ_VERSION_AFTER: Duration = Duration::from_secs(1);
const MAX_READ_VERSION_AGE: Duration = Duration::from_secs(4);
pub struct FdbStore {
db: Database,
version: ReadVersion,
}
pub(crate) struct ReadVersion {
base: Instant,
version: AtomicI64,
obtained: AtomicU64,
refreshing: AtomicBool,
}
impl ReadVersion {
fn now(&self) -> u64 {
self.base.elapsed().as_nanos() as u64
}
fn current(&self) -> i64 {
self.version.load(Ordering::Acquire)
}
fn age(&self) -> u64 {
self.now()
.saturating_sub(self.obtained.load(Ordering::Acquire))
}
fn store_max(&self, version: i64) {
let mut current = self.version.load(Ordering::Relaxed);
while version > current {
match self.version.compare_exchange_weak(
current,
version,
Ordering::Release,
Ordering::Relaxed,
) {
Ok(_) => break,
Err(actual) => current = actual,
}
}
}
fn refreshed(&self, version: i64) {
self.store_max(version);
self.obtained.store(self.now(), Ordering::Release);
}
fn raise_floor(&self, version: i64) {
self.store_max(version);
}
fn expire(&self) {
self.version.store(0, Ordering::Release);
}
fn try_begin_refresh(&self) -> Option<RefreshGuard<'_>> {
if self
.refreshing
.compare_exchange(false, true, Ordering::AcqRel, Ordering::Relaxed)
.is_ok()
{
Some(RefreshGuard(&self.refreshing))
} else {
None
}
}
}
impl Default for ReadVersion {
fn default() -> Self {
Self {
base: Instant::now(),
version: AtomicI64::new(0),
obtained: AtomicU64::new(0),
refreshing: AtomicBool::new(false),
}
}
}
pub(crate) struct RefreshGuard<'a>(&'a AtomicBool);
impl Drop for RefreshGuard<'_> {
fn drop(&mut self) {
self.0.store(false, Ordering::Release);
}
}
#[inline(always)]
fn into_error(error: FdbError) -> trc::Error {
trc::StoreEvent::FoundationdbError
.reason(error.message())
.ctx(trc::Key::Code, error.code())
}