fix(server): config & update handle (#15173)

#### PR Dependency Tree


* **PR #15173** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added native document update validation to check incoming Yjs updates
for decodability before applying them.
* Introduced support for validation timeouts and cancellation during
update checks.
* Blob maintenance jobs now detect when object storage is unavailable
and skip related work gracefully.

* **Bug Fixes**
* Invalid (and oversized) updates are now filtered out earlier during
document ingestion.
* Background blob maintenance continues processing other work even if
one workspace fails.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-06-29 22:59:17 +08:00
committed by GitHub
parent 1b9e21f2de
commit a1363b3873
13 changed files with 517 additions and 60 deletions
@@ -18,7 +18,7 @@ mod tests;
mod types;
mod workspace_stats;
use std::time::Duration;
use std::{sync::RwLock, time::Duration};
use napi::Result;
use sha2::{Digest, Sha256};
@@ -33,7 +33,7 @@ pub(super) fn token_hash(token: &str) -> String {
#[napi_derive::napi]
pub struct BackendRuntime {
config: RuntimeConfig,
config: RwLock<RuntimeConfig>,
pool: Mutex<Option<PgPool>>,
}
@@ -42,7 +42,7 @@ impl BackendRuntime {
#[napi(constructor)]
pub fn new() -> Result<Self> {
Ok(Self {
config: RuntimeConfig::from_config_files()?,
config: RwLock::new(RuntimeConfig::from_config_files()?),
pool: Mutex::new(None),
})
}
@@ -54,10 +54,11 @@ impl BackendRuntime {
return Ok(());
}
let database_url = self.config()?.database_url;
let pool = PgPoolOptions::new()
.max_connections(5)
.acquire_timeout(Duration::from_secs(5))
.connect(&self.config.database_url)
.connect(&database_url)
.await
.map_err(|err| napi_error(format!("BackendRuntime failed to connect postgres: {err}")))?;
@@ -66,6 +67,9 @@ impl BackendRuntime {
.await
.map_err(|err| napi_error(format!("BackendRuntime postgres health check failed: {err}")))?;
let config = self.config()?.with_db_overrides(&pool).await?;
self.update_config(config)?;
*guard = Some(pool);
Ok(())
}
@@ -94,7 +98,7 @@ impl BackendRuntime {
Ok(BackendRuntimeHealth {
started: pool.is_some(),
database_connected,
object_storage_configured: self.config.storage.is_some(),
object_storage_configured: self.config()?.storage.is_some(),
})
}
@@ -113,6 +117,22 @@ impl BackendRuntime {
.cloned()
.ok_or_else(|| napi_error("BackendRuntime must be started before using postgres operations"))
}
pub(in crate::backend_runtime) fn config(&self) -> Result<RuntimeConfig> {
self
.config
.read()
.map(|config| config.clone())
.map_err(|_| napi_error("BackendRuntime config lock poisoned"))
}
fn update_config(&self, config: RuntimeConfig) -> Result<()> {
*self
.config
.write()
.map_err(|_| napi_error("BackendRuntime config lock poisoned"))? = config;
Ok(())
}
}
async fn migrate_runtime_tables(pool: &PgPool) -> Result<()> {