fix(sql): replace Mutex with RwLock to enable concurrent SQL execution (#1972)

pull/1975/head
阿良仔 7 months ago committed by GitHub
parent 77149dc432
commit 4341d7f500
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
sql: patch
---
Replace `Mutex` with `RwLock` to enable concurrent SQL execution.

@ -23,7 +23,7 @@ pub(crate) async fn load<R: Runtime>(
pool.migrate(&migrator).await?; pool.migrate(&migrator).await?;
} }
db_instances.0.lock().await.insert(db.clone(), pool); db_instances.0.write().await.insert(db.clone(), pool);
Ok(db) Ok(db)
} }
@ -36,7 +36,7 @@ pub(crate) async fn close(
db_instances: State<'_, DbInstances>, db_instances: State<'_, DbInstances>,
db: Option<String>, db: Option<String>,
) -> Result<bool, crate::Error> { ) -> Result<bool, crate::Error> {
let mut instances = db_instances.0.lock().await; let instances = db_instances.0.read().await;
let pools = if let Some(db) = db { let pools = if let Some(db) = db {
vec![db] vec![db]
@ -45,9 +45,7 @@ pub(crate) async fn close(
}; };
for pool in pools { for pool in pools {
let db = instances let db = instances.get(&pool).ok_or(Error::DatabaseNotLoaded(pool))?;
.get_mut(&pool)
.ok_or(Error::DatabaseNotLoaded(pool))?;
db.close().await; db.close().await;
} }
@ -62,9 +60,9 @@ pub(crate) async fn execute(
query: String, query: String,
values: Vec<JsonValue>, values: Vec<JsonValue>,
) -> Result<(u64, LastInsertId), crate::Error> { ) -> Result<(u64, LastInsertId), crate::Error> {
let mut instances = db_instances.0.lock().await; let instances = db_instances.0.read().await;
let db = instances.get_mut(&db).ok_or(Error::DatabaseNotLoaded(db))?; let db = instances.get(&db).ok_or(Error::DatabaseNotLoaded(db))?;
db.execute(query, values).await db.execute(query, values).await
} }
@ -75,8 +73,8 @@ pub(crate) async fn select(
query: String, query: String,
values: Vec<JsonValue>, values: Vec<JsonValue>,
) -> Result<Vec<IndexMap<String, JsonValue>>, crate::Error> { ) -> Result<Vec<IndexMap<String, JsonValue>>, crate::Error> {
let mut instances = db_instances.0.lock().await; let instances = db_instances.0.read().await;
let db = instances.get_mut(&db).ok_or(Error::DatabaseNotLoaded(db))?; let db = instances.get(&db).ok_or(Error::DatabaseNotLoaded(db))?;
db.select(query, values).await db.select(query, values).await
} }

@ -29,12 +29,12 @@ use tauri::{
plugin::{Builder as PluginBuilder, TauriPlugin}, plugin::{Builder as PluginBuilder, TauriPlugin},
Manager, RunEvent, Runtime, Manager, RunEvent, Runtime,
}; };
use tokio::sync::Mutex; use tokio::sync::{Mutex, RwLock};
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Default)] #[derive(Default)]
pub struct DbInstances(pub Mutex<HashMap<String, DbPool>>); pub struct DbInstances(pub RwLock<HashMap<String, DbPool>>);
#[derive(Serialize)] #[derive(Serialize)]
#[serde(untagged)] #[serde(untagged)]
@ -140,7 +140,7 @@ impl Builder {
tauri::async_runtime::block_on(async move { tauri::async_runtime::block_on(async move {
let instances = DbInstances::default(); let instances = DbInstances::default();
let mut lock = instances.0.lock().await; let mut lock = instances.0.write().await;
for db in config.preload { for db in config.preload {
let pool = DbPool::connect(&db, app).await?; let pool = DbPool::connect(&db, app).await?;
@ -168,7 +168,7 @@ impl Builder {
if let RunEvent::Exit = event { if let RunEvent::Exit = event {
tauri::async_runtime::block_on(async move { tauri::async_runtime::block_on(async move {
let instances = &*app.state::<DbInstances>(); let instances = &*app.state::<DbInstances>();
let instances = instances.0.lock().await; let instances = instances.0.read().await;
for value in instances.values() { for value in instances.values() {
value.close().await; value.close().await;
} }

Loading…
Cancel
Save