From: phiresky Date: Fri, 14 Jul 2023 12:57:36 +0000 (+0200) Subject: work around race condition on community fetch (#3414) X-Git-Url: http://these/git/README.zh.hant.md?a=commitdiff_plain;h=2938b50908fb44c2f4dda61365ac7257021bf3c0;p=lemmy.git work around race condition on community fetch (#3414) --- diff --git a/crates/db_schema/src/impls/actor_language.rs b/crates/db_schema/src/impls/actor_language.rs index 592d62a3..eb68d2ee 100644 --- a/crates/db_schema/src/impls/actor_language.rs +++ b/crates/db_schema/src/impls/actor_language.rs @@ -275,25 +275,37 @@ impl CommunityLanguage { return Ok(()); } + let form = lang_ids + .into_iter() + .map(|language_id| CommunityLanguageForm { + community_id: for_community_id, + language_id, + }) + .collect::>(); + conn .build_transaction() .run(|conn| { Box::pin(async move { use crate::schema::community_language::dsl::{community_id, community_language}; + use diesel::result::DatabaseErrorKind::UniqueViolation; // Clear the current languages delete(community_language.filter(community_id.eq(for_community_id))) .execute(conn) .await?; - for l in lang_ids { - let form = CommunityLanguageForm { - community_id: for_community_id, - language_id: l, - }; - insert_into(community_language) - .values(form) - .get_result::(conn) - .await?; + let insert_res = insert_into(community_language) + .values(form) + .get_result::(conn) + .await; + + if let Err(Error::DatabaseError(UniqueViolation, _info)) = insert_res { + // race condition: this function was probably called simultaneously from another caller. ignore error + // tracing::warn!("unique error: {_info:#?}"); + // _info.constraint_name() should be = "community_language_community_id_language_id_key" + return Ok(()); + } else { + insert_res?; } Ok(()) }) as _