chore: fix pg lock (#298)

This commit is contained in:
Nathan.fooo 2024-02-06 08:57:10 +08:00 committed by GitHub
parent 1a7866e651
commit 1cfb38d7a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 11 additions and 63 deletions

View File

@ -517,10 +517,10 @@ pub async fn select_collab_members(
} }
#[inline] #[inline]
pub async fn select_collab_member( pub async fn select_collab_member<'a, E: Executor<'a, Database = Postgres>>(
uid: &i64, uid: &i64,
oid: &str, oid: &str,
pg_pool: &PgPool, executor: E,
) -> Result<AFCollabMember, AppError> { ) -> Result<AFCollabMember, AppError> {
let row = sqlx::query( let row = sqlx::query(
r#" r#"
@ -532,7 +532,7 @@ pub async fn select_collab_member(
) )
.bind(uid) .bind(uid)
.bind(oid) .bind(oid)
.fetch_one(pg_pool) .fetch_one(executor)
.await?; .await?;
let member = collab_member_try_from_row(row)?; let member = collab_member_try_from_row(row)?;

View File

@ -51,23 +51,11 @@ pub trait CollabStorageAccessControl: Send + Sync + 'static {
#[async_trait] #[async_trait]
pub trait CollabStorage: Send + Sync + 'static { pub trait CollabStorage: Send + Sync + 'static {
fn config(&self) -> &WriteConfig; fn config(&self) -> &WriteConfig;
/// Checks if a collaboration with the given object ID exists in the storage.
///
/// # Arguments
///
/// * `object_id` - A string slice that holds the ID of the collaboration.
///
/// # Returns
///
/// * `bool` - `true` if the collaboration exists, `false` otherwise.
async fn is_exist(&self, object_id: &str) -> bool;
async fn cache_collab(&self, object_id: &str, collab: Weak<MutexCollab>); async fn cache_collab(&self, object_id: &str, collab: Weak<MutexCollab>);
async fn remove_collab_cache(&self, object_id: &str); async fn remove_collab_cache(&self, object_id: &str);
async fn is_collab_exist(&self, oid: &str) -> DatabaseResult<bool>;
async fn upsert_collab(&self, uid: &i64, params: CreateCollabParams) -> DatabaseResult<()>; async fn upsert_collab(&self, uid: &i64, params: CreateCollabParams) -> DatabaseResult<()>;
/// Insert/update a new collaboration in the storage. /// Insert/update a new collaboration in the storage.
@ -136,10 +124,6 @@ where
self.as_ref().config() self.as_ref().config()
} }
async fn is_exist(&self, object_id: &str) -> bool {
self.as_ref().is_exist(object_id).await
}
async fn cache_collab(&self, object_id: &str, collab: Weak<MutexCollab>) { async fn cache_collab(&self, object_id: &str, collab: Weak<MutexCollab>) {
self.as_ref().cache_collab(object_id, collab).await self.as_ref().cache_collab(object_id, collab).await
} }
@ -148,10 +132,6 @@ where
self.as_ref().remove_collab_cache(object_id).await self.as_ref().remove_collab_cache(object_id).await
} }
async fn is_collab_exist(&self, oid: &str) -> DatabaseResult<bool> {
self.as_ref().is_collab_exist(oid).await
}
async fn upsert_collab(&self, uid: &i64, params: CreateCollabParams) -> DatabaseResult<()> { async fn upsert_collab(&self, uid: &i64, params: CreateCollabParams) -> DatabaseResult<()> {
self.as_ref().upsert_collab(uid, params).await self.as_ref().upsert_collab(uid, params).await
} }

View File

@ -310,8 +310,8 @@ pub async fn select_workspace_member_list(
} }
#[inline] #[inline]
pub async fn select_workspace_member( pub async fn select_workspace_member<'a, E: Executor<'a, Database = Postgres>>(
pg_pool: &PgPool, executor: E,
uid: &i64, uid: &i64,
workspace_id: &Uuid, workspace_id: &Uuid,
) -> Result<AFWorkspaceMemberRow, AppError> { ) -> Result<AFWorkspaceMemberRow, AppError> {
@ -327,7 +327,7 @@ pub async fn select_workspace_member(
workspace_id, workspace_id,
uid, uid,
) )
.fetch_one(pg_pool) .fetch_one(executor)
.await?; .await?;
Ok(member) Ok(member)
} }

View File

@ -368,10 +368,6 @@ pub struct CasbinWorkspaceAccessControl {
#[async_trait] #[async_trait]
impl WorkspaceAccessControl for CasbinWorkspaceAccessControl { impl WorkspaceAccessControl for CasbinWorkspaceAccessControl {
async fn get_role_from_uuid(&self, uid: &i64, workspace_id: &Uuid) -> Result<AFRole, AppError> {
self.get_role_from_uid(uid, workspace_id).await
}
async fn get_role_from_uid(&self, uid: &i64, workspace_id: &Uuid) -> Result<AFRole, AppError> { async fn get_role_from_uid(&self, uid: &i64, workspace_id: &Uuid) -> Result<AFRole, AppError> {
let policies = self let policies = self
.casbin_access_control .casbin_access_control

View File

@ -1,7 +1,8 @@
use async_trait::async_trait; use async_trait::async_trait;
use collab::core::collab::MutexCollab; use collab::core::collab::MutexCollab;
use database::collab::{ use database::collab::{
CollabStorage, CollabStorageAccessControl, CollabStoragePgImpl, DatabaseResult, WriteConfig, is_collab_exists, CollabStorage, CollabStorageAccessControl, CollabStoragePgImpl, DatabaseResult,
WriteConfig,
}; };
use database_entity::dto::{ use database_entity::dto::{
AFAccessLevel, AFSnapshotMeta, AFSnapshotMetas, CollabParams, CreateCollabParams, AFAccessLevel, AFSnapshotMeta, AFSnapshotMetas, CollabParams, CreateCollabParams,
@ -17,6 +18,7 @@ use anyhow::Context;
use app_error::AppError; use app_error::AppError;
use collab::core::collab_plugin::EncodedCollab; use collab::core::collab_plugin::EncodedCollab;
use sqlx::{PgPool, Transaction}; use sqlx::{PgPool, Transaction};
use std::ops::DerefMut;
use std::{ use std::{
collections::HashMap, collections::HashMap,
sync::{Arc, Weak}, sync::{Arc, Weak},
@ -82,10 +84,6 @@ where
self.disk_cache.config() self.disk_cache.config()
} }
async fn is_exist(&self, object_id: &str) -> bool {
self.disk_cache.is_exist(object_id).await
}
async fn cache_collab(&self, object_id: &str, collab: Weak<MutexCollab>) { async fn cache_collab(&self, object_id: &str, collab: Weak<MutexCollab>) {
tracing::trace!("cache opened collab:{}", object_id); tracing::trace!("cache opened collab:{}", object_id);
self self
@ -104,10 +102,6 @@ where
.remove(object_id); .remove(object_id);
} }
async fn is_collab_exist(&self, oid: &str) -> DatabaseResult<bool> {
self.disk_cache.is_collab_exist(oid).await
}
async fn upsert_collab(&self, uid: &i64, params: CreateCollabParams) -> DatabaseResult<()> { async fn upsert_collab(&self, uid: &i64, params: CreateCollabParams) -> DatabaseResult<()> {
let mut transaction = self let mut transaction = self
.disk_cache .disk_cache
@ -143,7 +137,7 @@ where
// 1. If the collab already exists, check if the user has enough permissions to update collab // 1. If the collab already exists, check if the user has enough permissions to update collab
// 2. If the collab doesn't exist, check if the user has enough permissions to create collab. // 2. If the collab doesn't exist, check if the user has enough permissions to create collab.
// TODO(nathan): remove is_collab_exist call and use access_control to check if the user has enough permissions to create collab. // TODO(nathan): remove is_collab_exist call and use access_control to check if the user has enough permissions to create collab.
let has_permission = if self.is_collab_exist(&params.object_id).await? { let has_permission = if is_collab_exists(&params.object_id, transaction.deref_mut()).await? {
// If the collab already exists, check if the user has enough permissions to update collab // If the collab already exists, check if the user has enough permissions to update collab
let level = self let level = self
.access_control .access_control

View File

@ -6,7 +6,7 @@ use actix_http::Method;
use async_trait::async_trait; use async_trait::async_trait;
use database::user::select_uid_from_uuid; use database::user::select_uid_from_uuid;
use sqlx::PgPool; use sqlx::{Executor, PgPool, Postgres};
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::collections::HashMap; use std::collections::HashMap;
@ -20,7 +20,6 @@ use uuid::Uuid;
#[async_trait] #[async_trait]
pub trait WorkspaceAccessControl: Send + Sync + 'static { pub trait WorkspaceAccessControl: Send + Sync + 'static {
async fn get_role_from_uuid(&self, uid: &i64, workspace_id: &Uuid) -> Result<AFRole, AppError>;
async fn get_role_from_uid(&self, uid: &i64, workspace_id: &Uuid) -> Result<AFRole, AppError>; async fn get_role_from_uid(&self, uid: &i64, workspace_id: &Uuid) -> Result<AFRole, AppError>;
async fn cache_role(&self, uid: &i64, workspace_id: &Uuid, role: AFRole) -> Result<(), AppError>; async fn cache_role(&self, uid: &i64, workspace_id: &Uuid, role: AFRole) -> Result<(), AppError>;
@ -179,27 +178,6 @@ fn spawn_listen_on_workspace_member_change(
}); });
} }
#[async_trait]
impl WorkspaceAccessControl for WorkspaceAccessControlImpl {
async fn get_role_from_uuid(&self, uid: &i64, workspace_id: &Uuid) -> Result<AFRole, AppError> {
let role = self.get_user_workspace_role(uid, workspace_id).await?;
Ok(role)
}
async fn get_role_from_uid(&self, uid: &i64, workspace_id: &Uuid) -> Result<AFRole, AppError> {
let role = self.get_user_workspace_role(uid, workspace_id).await?;
Ok(role)
}
async fn cache_role(&self, uid: &i64, workspace_id: &Uuid, role: AFRole) -> Result<(), AppError> {
Err(AppError::Internal(anyhow!("Not support")))
}
async fn remove_member(&self, uid: &i64, workspace_id: &Uuid) -> Result<(), AppError> {
Err(AppError::Internal(anyhow!("Not support")))
}
}
#[derive(Clone)] #[derive(Clone)]
pub struct WorkspaceHttpAccessControl<AC: WorkspaceAccessControl>(pub Arc<AC>); pub struct WorkspaceHttpAccessControl<AC: WorkspaceAccessControl>(pub Arc<AC>);
#[async_trait] #[async_trait]