mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-18 13:14:59 +01:00
Introduce run_db_operation_sync and run_db_operation
These functions are designed as a single funnel to talk to the database, whether it is synchronous or asynchronous. This single funnel will log SQL queries and slow operations, providing a clear and unified debug message for the problematic query, so it can be optimized accordingly (for instance, missing indexes or unbound SQL requests).
This commit is contained in:
@@ -1,13 +1,81 @@
|
||||
use std::fmt::Debug;
|
||||
use std::future::Future;
|
||||
use std::time::Instant;
|
||||
|
||||
use cdk_common::database::Error;
|
||||
|
||||
use crate::database::DatabaseExecutor;
|
||||
use crate::stmt::query;
|
||||
|
||||
const SLOW_QUERY_THRESHOLD_MS: u128 = 20;
|
||||
|
||||
/// Run a database operation and log slow operations, it also converts and logs any error with a
|
||||
/// given info for more context. This function is expecting a synchronous database operation
|
||||
#[inline(always)]
|
||||
pub fn run_db_operation_sync<F, E, E1, T>(
|
||||
info: &str,
|
||||
operation: F,
|
||||
error_map: E,
|
||||
) -> Result<T, Error>
|
||||
where
|
||||
F: FnOnce() -> Result<T, E1>,
|
||||
E1: Debug,
|
||||
E: FnOnce(E1) -> Error,
|
||||
{
|
||||
let start = Instant::now();
|
||||
|
||||
tracing::trace!("Running db operation {}", info);
|
||||
|
||||
let result = operation().map_err(|e| {
|
||||
tracing::error!("Query {} failed with error {:?}", info, e);
|
||||
error_map(e)
|
||||
});
|
||||
|
||||
let duration = start.elapsed();
|
||||
if duration.as_millis() > SLOW_QUERY_THRESHOLD_MS {
|
||||
tracing::warn!("[SLOW QUERY] Took {} ms: {}", duration.as_millis(), info);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Run a database operation and log slow operations, it also converts and logs any error with a
|
||||
/// given info for more context
|
||||
#[inline(always)]
|
||||
pub async fn run_db_operation<Fut, E, E1, T>(
|
||||
info: &str,
|
||||
operation: Fut,
|
||||
error_map: E,
|
||||
) -> Result<T, Error>
|
||||
where
|
||||
Fut: Future<Output = Result<T, E1>>,
|
||||
E1: Debug,
|
||||
E: FnOnce(E1) -> Error,
|
||||
{
|
||||
let start = Instant::now();
|
||||
|
||||
tracing::trace!("Running db operation {}", info);
|
||||
|
||||
let result = operation.await.map_err(|e| {
|
||||
tracing::error!("Query {} failed with error {:?}", info, e);
|
||||
error_map(e)
|
||||
});
|
||||
|
||||
let duration = start.elapsed();
|
||||
if duration.as_millis() > SLOW_QUERY_THRESHOLD_MS {
|
||||
tracing::warn!("[SLOW QUERY] Took {} ms: {}", duration.as_millis(), info);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Migrates the migration generated by `build.rs`
|
||||
#[inline(always)]
|
||||
pub async fn migrate<C>(
|
||||
conn: &C,
|
||||
db_prefix: &str,
|
||||
migrations: &[(&str, &str, &str)],
|
||||
) -> Result<(), cdk_common::database::Error>
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
C: DatabaseExecutor,
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ pub mod stmt;
|
||||
pub mod value;
|
||||
|
||||
pub use cdk_common::database::ConversionError;
|
||||
pub use common::{run_db_operation, run_db_operation_sync};
|
||||
|
||||
#[cfg(feature = "mint")]
|
||||
pub mod mint;
|
||||
|
||||
Reference in New Issue
Block a user