work around race condition on community fetch (#3414)

fix_hot_ranks_published
phiresky 2023-07-14 14:57:36 +02:00 committed by GitHub
parent 164f4b93d9
commit 2938b50908
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 21 additions and 9 deletions

View File

@ -275,25 +275,37 @@ impl CommunityLanguage {
return Ok(()); return Ok(());
} }
let form = lang_ids
.into_iter()
.map(|language_id| CommunityLanguageForm {
community_id: for_community_id,
language_id,
})
.collect::<Vec<_>>();
conn conn
.build_transaction() .build_transaction()
.run(|conn| { .run(|conn| {
Box::pin(async move { Box::pin(async move {
use crate::schema::community_language::dsl::{community_id, community_language}; use crate::schema::community_language::dsl::{community_id, community_language};
use diesel::result::DatabaseErrorKind::UniqueViolation;
// Clear the current languages // Clear the current languages
delete(community_language.filter(community_id.eq(for_community_id))) delete(community_language.filter(community_id.eq(for_community_id)))
.execute(conn) .execute(conn)
.await?; .await?;
for l in lang_ids { let insert_res = insert_into(community_language)
let form = CommunityLanguageForm { .values(form)
community_id: for_community_id, .get_result::<Self>(conn)
language_id: l, .await;
};
insert_into(community_language) if let Err(Error::DatabaseError(UniqueViolation, _info)) = insert_res {
.values(form) // race condition: this function was probably called simultaneously from another caller. ignore error
.get_result::<Self>(conn) // tracing::warn!("unique error: {_info:#?}");
.await?; // _info.constraint_name() should be = "community_language_community_id_language_id_key"
return Ok(());
} else {
insert_res?;
} }
Ok(()) Ok(())
}) as _ }) as _