v0.3.2-pre.007
This commit is contained in:
@@ -1,10 +1,122 @@
|
||||
// file: crates/ksp-store-postgres-lib/src/runtime.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
const APPLICATION_NAME: &str = "ksp-store";
|
||||
const MAX_CONNECTION_URI_BYTES: usize = 4_096;
|
||||
const SHUTDOWN_POLL_INTERVAL_MS: u64 = 10;
|
||||
|
||||
/// Safe PostgreSQL runtime counters exported only through the narrow backend bridge.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct PostgresBackendRuntimeSnapshot {
|
||||
pool_available: u32,
|
||||
pool_capacity: u32,
|
||||
pool_size: u32,
|
||||
pool_waiting: u32,
|
||||
}
|
||||
|
||||
impl PostgresBackendRuntimeSnapshot {
|
||||
/// Creates a safe pool-counter projection from already bounded values.
|
||||
#[must_use]
|
||||
pub(crate) const fn new(pool_capacity: u32, pool_size: u32, pool_available: u32, pool_waiting: u32) -> Self {
|
||||
return Self { pool_available, pool_capacity, pool_size, pool_waiting };
|
||||
}
|
||||
|
||||
/// Returns the number of currently available pooled PostgreSQL clients.
|
||||
#[must_use]
|
||||
pub const fn pool_available(&self) -> u32 {
|
||||
return self.pool_available;
|
||||
}
|
||||
|
||||
/// Returns the configured maximum pooled PostgreSQL client count.
|
||||
#[must_use]
|
||||
pub const fn pool_capacity(&self) -> u32 {
|
||||
return self.pool_capacity;
|
||||
}
|
||||
|
||||
/// Returns the current pooled PostgreSQL client count.
|
||||
#[must_use]
|
||||
pub const fn pool_size(&self) -> u32 {
|
||||
return self.pool_size;
|
||||
}
|
||||
|
||||
/// Returns the number of tasks currently waiting for a pooled PostgreSQL client.
|
||||
#[must_use]
|
||||
pub const fn pool_waiting(&self) -> u32 {
|
||||
return self.pool_waiting;
|
||||
}
|
||||
}
|
||||
|
||||
/// Safe PostgreSQL readiness projection returned to the common Store facade.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct PostgresBackendHealthSnapshot {
|
||||
error_kind: std::option::Option<crate::PostgresBackendErrorKind>,
|
||||
migration_version: std::option::Option<u64>,
|
||||
pending_migration_count: u32,
|
||||
ready: bool,
|
||||
runtime: PostgresBackendRuntimeSnapshot,
|
||||
}
|
||||
|
||||
impl PostgresBackendHealthSnapshot {
|
||||
/// Creates one successful safe readiness projection.
|
||||
#[must_use]
|
||||
pub(crate) const fn ready(runtime: PostgresBackendRuntimeSnapshot, migration_version: u64, pending_migration_count: u32) -> Self {
|
||||
return Self {
|
||||
error_kind: std::option::Option::None,
|
||||
migration_version: std::option::Option::Some(migration_version),
|
||||
pending_migration_count,
|
||||
ready: true,
|
||||
runtime,
|
||||
};
|
||||
}
|
||||
|
||||
/// Creates one failed safe readiness projection from a classified backend error.
|
||||
#[must_use]
|
||||
pub(crate) const fn not_ready(
|
||||
runtime: PostgresBackendRuntimeSnapshot,
|
||||
migration_version: std::option::Option<u64>,
|
||||
pending_migration_count: u32,
|
||||
error_kind: crate::PostgresBackendErrorKind,
|
||||
) -> Self {
|
||||
return Self {
|
||||
error_kind: std::option::Option::Some(error_kind),
|
||||
migration_version,
|
||||
pending_migration_count,
|
||||
ready: false,
|
||||
runtime,
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the safe backend error classification when readiness could not be proven.
|
||||
#[must_use]
|
||||
pub const fn error_kind(&self) -> std::option::Option<crate::PostgresBackendErrorKind> {
|
||||
return self.error_kind;
|
||||
}
|
||||
|
||||
/// Returns whether the latest bounded PostgreSQL probe proved readiness.
|
||||
#[must_use]
|
||||
pub const fn is_ready(&self) -> bool {
|
||||
return self.ready;
|
||||
}
|
||||
|
||||
/// Returns the migration version observed by the readiness probe when available.
|
||||
#[must_use]
|
||||
pub const fn migration_version(&self) -> std::option::Option<u64> {
|
||||
return self.migration_version;
|
||||
}
|
||||
|
||||
/// Returns the number of embedded migrations newer than the observed applied version.
|
||||
#[must_use]
|
||||
pub const fn pending_migration_count(&self) -> u32 {
|
||||
return self.pending_migration_count;
|
||||
}
|
||||
|
||||
/// Returns the safe PostgreSQL pool counters captured for this probe.
|
||||
#[must_use]
|
||||
pub const fn runtime(&self) -> &PostgresBackendRuntimeSnapshot {
|
||||
return &self.runtime;
|
||||
}
|
||||
}
|
||||
|
||||
/// TLS mode accepted by the physical PostgreSQL backend bridge.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
@@ -165,6 +277,17 @@ impl PostgresBackend {
|
||||
return std::result::Result::Ok(Self { network: settings.network, pool });
|
||||
}
|
||||
|
||||
/// Returns a safe synchronous snapshot of bounded pool counters without performing PostgreSQL I/O.
|
||||
#[must_use]
|
||||
pub fn runtime_snapshot(&self) -> PostgresBackendRuntimeSnapshot {
|
||||
return runtime_snapshot_from_status(self.pool.status());
|
||||
}
|
||||
|
||||
/// Runs a bounded lightweight PostgreSQL readiness probe and returns only safe classified diagnostics.
|
||||
pub async fn health(&self) -> PostgresBackendHealthSnapshot {
|
||||
return crate::probe_health(&self.pool).await;
|
||||
}
|
||||
|
||||
/// Explicitly closes the pool and waits for all owned pooled objects to drain inside the supplied bound.
|
||||
pub async fn close(self, timeout: std::time::Duration) -> std::result::Result<(), crate::PostgresBackendError> {
|
||||
self.pool.close();
|
||||
@@ -304,7 +427,8 @@ fn build_verified_tls() -> std::result::Result<tokio_postgres_rustls::MakeRustls
|
||||
return std::result::Result::Ok(tokio_postgres_rustls::MakeRustlsConnect::new(client_config));
|
||||
}
|
||||
|
||||
fn map_pool_error(error: deadpool_postgres::PoolError) -> crate::PostgresBackendError {
|
||||
/// Maps one Deadpool acquisition error into a redacted backend classification.
|
||||
pub(crate) fn map_pool_error(error: deadpool_postgres::PoolError) -> crate::PostgresBackendError {
|
||||
return match error {
|
||||
deadpool_postgres::PoolError::Timeout(timeout_type) => crate::PostgresBackendError::new(
|
||||
crate::PostgresBackendErrorKind::PoolTimeout,
|
||||
@@ -321,6 +445,23 @@ fn map_pool_error(error: deadpool_postgres::PoolError) -> crate::PostgresBackend
|
||||
};
|
||||
}
|
||||
|
||||
/// Converts Deadpool status into a bounded safe backend runtime projection.
|
||||
pub(crate) fn runtime_snapshot_from_status(status: deadpool_postgres::Status) -> PostgresBackendRuntimeSnapshot {
|
||||
return PostgresBackendRuntimeSnapshot::new(
|
||||
bounded_count(status.max_size),
|
||||
bounded_count(status.size),
|
||||
bounded_count(status.available),
|
||||
bounded_count(status.waiting),
|
||||
);
|
||||
}
|
||||
|
||||
fn bounded_count(value: usize) -> u32 {
|
||||
if value > u32::MAX as usize {
|
||||
return u32::MAX;
|
||||
}
|
||||
return value as u32;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "../unit_tests/runtime.rs"]
|
||||
mod tests;
|
||||
|
||||
Reference in New Issue
Block a user