perf(fleet): cache grouped views with revision-based invalidation
This commit is contained in:
13 files changed
+493
-11
No files matched your search
@@ -16,8 +16,20 @@ use crate::state::types::{
|
||||
pub struct Store {
|
||||
db_path: PathBuf,
|
||||
pool: SqlitePool,
|
||||
fleet_revision: std::sync::atomic::AtomicU64,
|
||||
}
|
||||
impl Store {
|
||||
pub(crate) fn fleet_revision(&self) -> u64 {
|
||||
self.fleet_revision
|
||||
.load(std::sync::atomic::Ordering::Acquire)
|
||||
}
|
||||
|
||||
/// Call after a successful fleet-relevant write, never before its commit.
|
||||
fn touch_fleet(&self) {
|
||||
self.fleet_revision
|
||||
.fetch_add(1, std::sync::atomic::Ordering::Release);
|
||||
}
|
||||
|
||||
/// Begins a new transaction with an IMMEDIATE write lock.
|
||||
///
|
||||
/// Use this for all transactions that perform writes to avoid SQLite upgrade deadlocks.
|
||||
|
||||
@@ -32,6 +32,9 @@ impl Store {
|
||||
tx.commit()
|
||||
.await
|
||||
.context("failed committing device retention cleanup")?;
|
||||
if removed > 0 {
|
||||
self.touch_fleet();
|
||||
}
|
||||
Ok(removed)
|
||||
}
|
||||
|
||||
@@ -251,6 +254,7 @@ impl Store {
|
||||
tx.commit()
|
||||
.await
|
||||
.context("failed committing device snapshot")?;
|
||||
self.touch_fleet();
|
||||
|
||||
tracing::Span::current().record("accepted", incoming_keys.len());
|
||||
Ok(incoming_keys.len())
|
||||
@@ -644,10 +648,12 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
let before_cleanup = store.fleet_revision();
|
||||
assert_eq!(
|
||||
store.prune_devices_at(Duration::ZERO, 1_000).await.unwrap(),
|
||||
0
|
||||
);
|
||||
assert_eq!(store.fleet_revision(), before_cleanup);
|
||||
assert_eq!(
|
||||
store
|
||||
.prune_devices_at(Duration::from_secs(900), 1_000)
|
||||
@@ -655,6 +661,8 @@ mod tests {
|
||||
.unwrap(),
|
||||
1
|
||||
);
|
||||
let after_cleanup = store.fleet_revision();
|
||||
assert_ne!(after_cleanup, before_cleanup);
|
||||
assert_eq!(
|
||||
store
|
||||
.prune_devices_at(Duration::from_secs(900), 1_000)
|
||||
@@ -662,6 +670,7 @@ mod tests {
|
||||
.unwrap(),
|
||||
0
|
||||
);
|
||||
assert_eq!(store.fleet_revision(), after_cleanup);
|
||||
|
||||
for table in [
|
||||
"agent_devices",
|
||||
|
||||
@@ -25,7 +25,11 @@ impl Store {
|
||||
.await
|
||||
.with_context(|| format!("failed to migrate state db {}", db_path.display()))?;
|
||||
|
||||
let store = Self { db_path, pool };
|
||||
let store = Self {
|
||||
db_path,
|
||||
pool,
|
||||
fleet_revision: Default::default(),
|
||||
};
|
||||
|
||||
store.ensure_schema_version().await?;
|
||||
store
|
||||
@@ -87,7 +91,8 @@ impl Store {
|
||||
.fetch_one(&self.pool)
|
||||
.await
|
||||
.context("failed validating SQLite state connection")?;
|
||||
info!(path = %self.db_path.display(), "reload requested; SQLite backend does not require in-memory reload");
|
||||
self.touch_fleet();
|
||||
info!(path = %self.db_path.display(), "reload requested; invalidated derived fleet views");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ impl Store {
|
||||
tx.commit()
|
||||
.await
|
||||
.context("failed committing known device transaction")?;
|
||||
self.touch_fleet();
|
||||
self.get_known_device(&device_id)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow::anyhow!("created known device disappeared"))
|
||||
@@ -84,6 +85,7 @@ impl Store {
|
||||
if result.rows_affected() == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
self.touch_fleet();
|
||||
self.get_known_device(device_id).await
|
||||
}
|
||||
|
||||
@@ -93,6 +95,9 @@ impl Store {
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.context("failed deleting known device")?;
|
||||
if result.rows_affected() > 0 {
|
||||
self.touch_fleet();
|
||||
}
|
||||
Ok(result.rows_affected() > 0)
|
||||
}
|
||||
|
||||
@@ -159,6 +164,7 @@ impl Store {
|
||||
tx.commit()
|
||||
.await
|
||||
.context("failed committing known device merge transaction")?;
|
||||
self.touch_fleet();
|
||||
self.get_known_device(target_device_id).await
|
||||
}
|
||||
|
||||
@@ -195,6 +201,7 @@ impl Store {
|
||||
tx.commit()
|
||||
.await
|
||||
.context("failed committing device identifier transaction")?;
|
||||
self.touch_fleet();
|
||||
self.get_known_device(device_id).await
|
||||
}
|
||||
|
||||
@@ -237,6 +244,7 @@ impl Store {
|
||||
tx.commit()
|
||||
.await
|
||||
.context("failed committing device identifier detach transaction")?;
|
||||
self.touch_fleet();
|
||||
self.get_known_device(device_id).await
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ impl Store {
|
||||
tx.commit()
|
||||
.await
|
||||
.context("failed committing state db after enroll")?;
|
||||
self.touch_fleet();
|
||||
info!(agent_id = %agent_id, "issued persistent agent credentials");
|
||||
|
||||
Ok(IssuedAgent {
|
||||
@@ -113,6 +114,9 @@ impl Store {
|
||||
tx.commit()
|
||||
.await
|
||||
.context("failed committing db after agent revoke")?;
|
||||
if result.rows_affected() > 0 {
|
||||
self.touch_fleet();
|
||||
}
|
||||
Ok(result.rows_affected() > 0)
|
||||
}
|
||||
|
||||
@@ -146,6 +150,7 @@ impl Store {
|
||||
.context("failed clearing agent nickname")?;
|
||||
}
|
||||
|
||||
self.touch_fleet();
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user