feat: add DB connection retry logic with get_conn() helper
This commit is contained in:
parent
e09a0f4616
commit
593666135c
@ -5,7 +5,7 @@ use dioxus::prelude::*;
|
||||
use http::header::{HeaderValue, SET_COOKIE};
|
||||
|
||||
use crate::auth::{password, session};
|
||||
use crate::db::pool::DB_POOL;
|
||||
use crate::db::pool::get_conn;
|
||||
use crate::models::user::{PublicUser, User, UserRole};
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -85,7 +85,7 @@ pub async fn register(
|
||||
});
|
||||
}
|
||||
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("Register DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -142,7 +142,7 @@ pub async fn register(
|
||||
|
||||
#[server(Login, "/api")]
|
||||
pub async fn login(username: String, password: String) -> Result<AuthResponse, ServerFnError> {
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("Login DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -228,7 +228,7 @@ pub async fn logout() -> Result<AuthResponse, ServerFnError> {
|
||||
None
|
||||
};
|
||||
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("Logout DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -282,7 +282,7 @@ pub async fn get_current_user() -> Result<CurrentUserResponse, ServerFnError> {
|
||||
return Ok(CurrentUserResponse { user: None });
|
||||
};
|
||||
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("GetCurrentUser DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::db::pool::DB_POOL;
|
||||
use crate::db::pool::get_conn;
|
||||
use crate::models::post::{Post, PostStats, PostStatus, Tag};
|
||||
use crate::models::user::{User, UserRole};
|
||||
|
||||
@ -42,7 +42,7 @@ async fn get_current_admin_user() -> Result<User, ServerFnError> {
|
||||
return Err(ServerFnError::new("未登录"));
|
||||
};
|
||||
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -782,7 +782,7 @@ pub async fn create_post(
|
||||
_ => slugify(&title),
|
||||
};
|
||||
|
||||
let mut client = DB_POOL.get().await.map_err(|e| {
|
||||
let mut client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -910,7 +910,7 @@ pub async fn update_post(
|
||||
) -> Result<CreatePostResponse, ServerFnError> {
|
||||
let user = get_current_admin_user().await?;
|
||||
|
||||
let mut client = DB_POOL.get().await.map_err(|e| {
|
||||
let mut client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -1086,7 +1086,7 @@ pub async fn update_post(
|
||||
|
||||
#[server(GetPostBySlug, "/api")]
|
||||
pub async fn get_post_by_slug(slug: String) -> Result<SinglePostResponse, ServerFnError> {
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -1137,7 +1137,7 @@ pub async fn list_published_posts(
|
||||
page: i32,
|
||||
per_page: i32,
|
||||
) -> Result<PostListResponse, ServerFnError> {
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -1171,7 +1171,7 @@ pub async fn list_published_posts(
|
||||
pub async fn list_posts() -> Result<PostListResponse, ServerFnError> {
|
||||
let _user = get_current_admin_user().await?;
|
||||
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -1202,7 +1202,7 @@ pub async fn list_posts() -> Result<PostListResponse, ServerFnError> {
|
||||
pub async fn delete_post(post_id: i32) -> Result<CreatePostResponse, ServerFnError> {
|
||||
let _user = get_current_admin_user().await?;
|
||||
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -1237,7 +1237,7 @@ pub async fn delete_post(post_id: i32) -> Result<CreatePostResponse, ServerFnErr
|
||||
|
||||
#[server(ListTags, "/api")]
|
||||
pub async fn list_tags() -> Result<TagListResponse, ServerFnError> {
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -1272,7 +1272,7 @@ pub async fn list_tags() -> Result<TagListResponse, ServerFnError> {
|
||||
|
||||
#[server(GetPostsByTag, "/api")]
|
||||
pub async fn get_posts_by_tag(tag_name: String) -> Result<PostListResponse, ServerFnError> {
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -1305,7 +1305,7 @@ pub async fn get_posts_by_tag(tag_name: String) -> Result<PostListResponse, Serv
|
||||
pub async fn get_post_stats() -> Result<PostStatsResponse, ServerFnError> {
|
||||
let _user = get_current_admin_user().await?;
|
||||
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
@ -1345,7 +1345,7 @@ pub async fn get_post_stats() -> Result<PostStatsResponse, ServerFnError> {
|
||||
|
||||
#[server(SearchPosts, "/api")]
|
||||
pub async fn search_posts(query: String) -> Result<PostListResponse, ServerFnError> {
|
||||
let client = DB_POOL.get().await.map_err(|e| {
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
|
||||
@ -11,4 +11,8 @@ pub mod pool {
|
||||
}
|
||||
}
|
||||
pub static DB_POOL: DummyPool = DummyPool;
|
||||
|
||||
pub async fn get_conn() -> Result<(), ()> {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use std::sync::LazyLock;
|
||||
use std::time::Duration;
|
||||
|
||||
use deadpool_postgres::{Manager, ManagerConfig, Pool, RecyclingMethod};
|
||||
use tokio_postgres::NoTls;
|
||||
@ -19,3 +20,23 @@ pub static DB_POOL: LazyLock<Pool> = LazyLock::new(|| {
|
||||
.build()
|
||||
.expect("Failed to create database connection pool")
|
||||
});
|
||||
|
||||
const MAX_RETRIES: u32 = 3;
|
||||
const RETRY_DELAY: Duration = Duration::from_secs(2);
|
||||
|
||||
pub async fn get_conn() -> Result<deadpool_postgres::Object, deadpool_postgres::PoolError> {
|
||||
let mut last_err = None;
|
||||
for attempt in 0..=MAX_RETRIES {
|
||||
match DB_POOL.get().await {
|
||||
Ok(conn) => return Ok(conn),
|
||||
Err(e) => {
|
||||
if attempt < MAX_RETRIES {
|
||||
tracing::warn!("DB connection attempt {} failed, retrying in {:?}: {:?}", attempt + 1, RETRY_DELAY, e);
|
||||
tokio::time::sleep(RETRY_DELAY).await;
|
||||
}
|
||||
last_err = Some(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(last_err.unwrap())
|
||||
}
|
||||
|
||||
@ -2,13 +2,13 @@ use std::time::Duration;
|
||||
|
||||
use tokio::time::interval;
|
||||
|
||||
use crate::db::pool::DB_POOL;
|
||||
use crate::db::pool::get_conn;
|
||||
|
||||
pub async fn run_cleanup() {
|
||||
let mut ticker = interval(Duration::from_secs(3600));
|
||||
loop {
|
||||
ticker.tick().await;
|
||||
match DB_POOL.get().await {
|
||||
match get_conn().await {
|
||||
Ok(client) => {
|
||||
if let Err(e) = client
|
||||
.execute("DELETE FROM sessions WHERE expires_at < NOW()", &[])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user