From f5d7a99a70f570ddbb2ecdebf582efcfd1b3c08f Mon Sep 17 00:00:00 2001 From: jake <77554505+brxken128@users.noreply.github.com> Date: Thu, 22 Jun 2023 11:49:21 +0100 Subject: [PATCH] [ENG-737] Location deletion hanging (#978) * fix concurrency issue with lib deletion * clear only completed jobs * slight fixes * experimental but faster i think * lower chunk size --- core/src/api/jobs.rs | 10 +++++++++- core/src/library/manager.rs | 4 ++-- core/src/location/mod.rs | 37 +++++++++---------------------------- 3 files changed, 20 insertions(+), 31 deletions(-) diff --git a/core/src/api/jobs.rs b/core/src/api/jobs.rs index f16e90c9d..3baf52dfb 100644 --- a/core/src/api/jobs.rs +++ b/core/src/api/jobs.rs @@ -173,7 +173,15 @@ pub(crate) fn mount() -> AlphaRouter { .procedure("clearAll", { R.with2(library()) .mutation(|(_, library), _: ()| async move { - library.db.job().delete_many(vec![]).exec().await?; + library + .db + .job() + .delete_many(vec![ + job::status::equals(Some(JobStatus::Completed as i32)), + job::status::equals(Some(JobStatus::CompletedWithErrors as i32)), + ]) + .exec() + .await?; invalidate_query!(library, "jobs.reports"); Ok(()) diff --git a/core/src/library/manager.rs b/core/src/library/manager.rs index 0b26e765e..2ed9064b7 100644 --- a/core/src/library/manager.rs +++ b/core/src/library/manager.rs @@ -338,7 +338,7 @@ impl LibraryManager { } pub async fn delete(&self, id: Uuid) -> Result<(), LibraryManagerError> { - let mut libraries = self.libraries.write().await; + let libraries = self.libraries.read().await; let library = libraries .iter() @@ -363,7 +363,7 @@ impl LibraryManager { invalidate_query!(library, "library.list"); - libraries.retain(|l| l.id != id); + self.libraries.write().await.retain(|l| l.id != id); Ok(()) } diff --git a/core/src/location/mod.rs b/core/src/location/mod.rs index fd761226e..2f37f1047 100644 --- a/core/src/location/mod.rs +++ b/core/src/location/mod.rs @@ -7,7 +7,7 @@ use crate::{ file_identifier::{self, file_identifier_job::FileIdentifierJobInit}, preview::{shallow_thumbnailer, thumbnailer_job::ThumbnailerJobInit}, }, - prisma::{file_path, indexer_rules_in_location, location, node, object, PrismaClient}, + prisma::{file_path, indexer_rules_in_location, location, node, PrismaClient}, sync, util::{ db::{chain_optional_iter, uuid_to_bytes}, @@ -18,15 +18,17 @@ use crate::{ use std::{ collections::HashSet, path::{Component, Path, PathBuf}, + time::Instant, }; use futures::future::TryFutureExt; +use itertools::Itertools; use normpath::PathExt; use prisma_client_rust::{operator::and, or, QueryError}; use serde::Deserialize; use serde_json::json; use specta::Type; -use tokio::{fs, io}; +use tokio::{fs, io, task}; use tracing::{debug, info}; use uuid::Uuid; @@ -661,10 +663,9 @@ pub async fn delete_location( } } - library.orphan_remover.invoke().await; + invalidate_query!(library, "locations.list"); info!("Location {} deleted", location_id); - invalidate_query!(library, "locations.list"); Ok(()) } @@ -692,31 +693,11 @@ pub async fn delete_directory( })], ); - // Fetching all object_ids from all children file_paths - let object_ids = db - .file_path() - .find_many(children_params.clone()) - .select(file_path::select!({ object_id })) - .exec() - .await? - .into_iter() - .filter_map(|file_path| file_path.object_id) - .collect(); - - // WARNING: file_paths must be deleted before objects, as they reference objects through object_id - // delete all children file_paths - db.file_path().delete_many(children_params).exec().await?; - - // delete all children objects - db.object() - .delete_many(vec![ - object::id::in_vec(object_ids), - // https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#none - object::file_paths::none(vec![]), - ]) - .exec() - .await?; + for params in children_params.chunks(512) { + db.file_path().delete_many(params.to_vec()).exec().await?; + } + library.orphan_remover.invoke().await; invalidate_query!(library, "search.paths"); Ok(())