chore: remove pg advisory lock

This commit is contained in:
Bartosz Sypytkowski 2024-07-15 19:09:26 +02:00
parent eebdbcad79
commit f5ca71e701
5 changed files with 30 additions and 67 deletions

View File

@ -1,22 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "SELECT pg_advisory_xact_lock($1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "pg_advisory_xact_lock",
"type_info": "Void"
}
],
"parameters": {
"Left": [
"Int8"
]
},
"nullable": [
null
]
},
"hash": "a06e1d9f6f95e4c4c2b98310ebddcc9d963cc033582bf2e945e8bf3a301b4247"
}

View File

@ -1,25 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "\n WITH ins_user AS (\n INSERT INTO af_user (uid, uuid, email, name)\n VALUES ($1, $2, $3, $4)\n ON CONFLICT(email) DO NOTHING\n RETURNING uid\n ),\n owner_role AS (\n SELECT id FROM af_roles WHERE name = 'Owner'\n ),\n ins_workspace AS (\n INSERT INTO af_workspace (owner_uid)\n SELECT uid FROM ins_user\n RETURNING workspace_id, owner_uid\n ),\n ins_collab_member AS (\n INSERT INTO af_collab_member (uid, oid, permission_id)\n SELECT ins_workspace.owner_uid,\n ins_workspace.workspace_id::TEXT,\n (SELECT permission_id FROM af_role_permissions WHERE role_id = owner_role.id)\n FROM ins_workspace, owner_role\n )\n SELECT workspace_id FROM ins_workspace;\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "workspace_id",
"type_info": "Uuid"
}
],
"parameters": {
"Left": [
"Int8",
"Uuid",
"Text",
"Text"
]
},
"nullable": [
false
]
},
"hash": "b4fa2e732c975fbb23c346981c4fb1e2e0aab6f3a1ac9c2fc99b4cdee9e58cbe"
}

View File

@ -0,0 +1,25 @@
{
"db_name": "PostgreSQL",
"query": "\n WITH ins_user AS (\n INSERT INTO af_user (uid, uuid, email, name)\n VALUES ($1, $2, $3, $4)\n RETURNING uid\n ),\n owner_role AS (\n SELECT id FROM af_roles WHERE name = 'Owner'\n ),\n ins_workspace AS (\n INSERT INTO af_workspace (owner_uid)\n SELECT uid FROM ins_user\n RETURNING workspace_id, owner_uid\n ),\n ins_collab_member AS (\n INSERT INTO af_collab_member (uid, oid, permission_id)\n SELECT ins_workspace.owner_uid,\n ins_workspace.workspace_id::TEXT,\n (SELECT permission_id FROM af_role_permissions WHERE role_id = owner_role.id)\n FROM ins_workspace, owner_role\n )\n SELECT workspace_id FROM ins_workspace;\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "workspace_id",
"type_info": "Uuid"
}
],
"parameters": {
"Left": [
"Int8",
"Uuid",
"Text",
"Text"
]
},
"nullable": [
false
]
},
"hash": "ce3b2a3ddee0f420166719e39e0e4befa495bb6438ef88be860fa1e557bf9281"
}

View File

@ -1,12 +1,14 @@
use crate::pg_row::AFUserIdRow;
use app_error::AppError;
use futures_util::stream::BoxStream;
use sqlx::{Arguments, Executor, PgPool, Postgres};
use sqlx::postgres::PgArguments;
use sqlx::types::JsonValue;
use sqlx::{Arguments, Executor, PgPool, Postgres};
use tracing::{instrument, warn};
use uuid::Uuid;
use app_error::AppError;
use crate::pg_row::AFUserIdRow;
/// Updates the user's details in the `af_user` table.
///
/// This function allows for updating the user's name, email, and metadata based on the provided UUID.
@ -104,7 +106,6 @@ pub async fn create_user<'a, E: Executor<'a, Database = Postgres>>(
WITH ins_user AS (
INSERT INTO af_user (uid, uuid, email, name)
VALUES ($1, $2, $3, $4)
ON CONFLICT(email) DO NOTHING
RETURNING uid
),
owner_role AS (

View File

@ -23,28 +23,12 @@ pub async fn verify_token(access_token: &str, state: &AppState) -> Result<bool,
let user_uuid = uuid::Uuid::parse_str(&user.id)?;
let name = name_from_user_metadata(&user.user_metadata);
let is_new = !is_user_exist(&state.pg_pool, &user_uuid).await?;
if !is_new {
return Ok(false);
}
let mut txn = state
.pg_pool
.begin()
.await
.context("acquire transaction to verify token")?;
// To prevent concurrent creation of the same user with the same workspace resources, we lock
// the user row when `verify_token` is called. This means that if multiple requests try to
// create the same user simultaneously, the first request will acquire the lock, create the user,
// and any subsequent requests will wait for the lock to be released. After the lock is released,
// the other requests will proceed and return the result, ensuring that each user is created only once
// and avoiding duplicate entries.
let lock_key = user_uuid.as_u128() as i64;
sqlx::query!("SELECT pg_advisory_xact_lock($1)", lock_key)
.execute(txn.deref_mut())
.await?;
let is_new = !is_user_exist(txn.deref_mut(), &user_uuid).await?;
if is_new {
let new_uid = state.id_gen.write().await.next_id();