fix: ent deadlock with sqlite (#6878)

Issue was that we use a lock function to lock sqlite client when doing
write ops, because only one thread should do them at a time. However,
the client init also requires a lock. When running ent version, ent init
had a function which would lock as well as be the first one to access
the client, hence deadlock on the client lock.

This issue was not there when running for the first time, because in
migration function we init clients without the locks. However when
running second time, the migration returns early, and does not int
clients hence the ent function deadlocks, and subsequently locks
everything that need the db access.

The fix is simple, in migration function move the client init before
return, so that we always have an initialized client and do not get
deadlocked in ent or non ent version.

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>
Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com>
This commit is contained in:
Yashodhan Joshi
2025-05-22 16:34:48 +05:30
committed by GitHub
co-authored by Yashodhan Joshi
parent f683003e8e
commit eaff74ee9d
+2 -1
View File
@@ -80,6 +80,8 @@ async fn upgrade_resource_names() -> Result<(), anyhow::Error> {
}
pub async fn init_db() -> std::result::Result<(), anyhow::Error> {
// we init client here to avoid deadlocks
ORM_CLIENT.get_or_init(connect_to_orm).await;
let db_schema_version = match infra::get_db_schema_version().await {
Ok(v) => v,
Err(e) => {
@@ -101,7 +103,6 @@ pub async fn init_db() -> std::result::Result<(), anyhow::Error> {
infra::db_init().await?;
// we initialize both clients here to avoid potential deadlock afterwards
ORM_CLIENT.get_or_init(connect_to_orm).await;
ORM_CLIENT_DDL.get_or_init(connect_to_orm_ddl).await;
// check version upgrade
let old_version = version::get().await.unwrap_or("v0.0.0".to_string());