add explicit quick_check/disable_synchronous flags, ?full param to rescan endpoint
parent
466f870d6f
commit
9c940e7c23
|
@ -53,7 +53,8 @@ fn initialize_types(connection: &UpEndConnection) -> Result<()> {
|
|||
pub async fn rescan_vault(
|
||||
db: Arc<UpEndDatabase>,
|
||||
job_container: Arc<RwLock<JobContainer>>,
|
||||
initial: bool,
|
||||
quick_check: bool,
|
||||
disable_synchronous: bool,
|
||||
) {
|
||||
let add_result = job_container
|
||||
.write()
|
||||
|
@ -63,7 +64,13 @@ pub async fn rescan_vault(
|
|||
if let Ok(job_id) = add_result {
|
||||
let job_container_rescan = job_container.clone();
|
||||
let result = actix_web::web::block(move || {
|
||||
rescan_vault_inner(db, job_container_rescan, job_id, initial)
|
||||
rescan_vault_inner(
|
||||
db,
|
||||
job_container_rescan,
|
||||
job_id,
|
||||
quick_check,
|
||||
disable_synchronous,
|
||||
)
|
||||
})
|
||||
.await;
|
||||
|
||||
|
@ -108,7 +115,8 @@ fn rescan_vault_inner<D: Borrow<UpEndDatabase>>(
|
|||
db: D,
|
||||
job_container: Arc<RwLock<JobContainer>>,
|
||||
job_id: JobId,
|
||||
initial: bool,
|
||||
quick_check: bool,
|
||||
disable_synchronous: bool,
|
||||
) -> Result<Vec<UpdatePathOutcome>> {
|
||||
let start = Instant::now();
|
||||
info!("Vault rescan started.");
|
||||
|
@ -122,7 +130,7 @@ fn rescan_vault_inner<D: Borrow<UpEndDatabase>>(
|
|||
|
||||
// Disable syncing in SQLite for the duration of the import
|
||||
let mut _guard: Option<PragmaSynchronousGuard> = None;
|
||||
if initial {
|
||||
if disable_synchronous {
|
||||
debug!("Disabling SQLite synchronous mode");
|
||||
connection.execute("PRAGMA synchronous = OFF;")?;
|
||||
_guard = Some(PragmaSynchronousGuard(&connection));
|
||||
|
@ -155,6 +163,7 @@ fn rescan_vault_inner<D: Borrow<UpEndDatabase>>(
|
|||
&resolve_cache,
|
||||
path.clone(),
|
||||
&existing_files,
|
||||
quick_check,
|
||||
);
|
||||
|
||||
let mut cnt = count.write().unwrap();
|
||||
|
@ -245,6 +254,7 @@ fn process_directory_entry(
|
|||
resolve_cache: &Arc<Mutex<ResolveCache>>,
|
||||
path: PathBuf,
|
||||
existing_files: &Arc<RwLock<Vec<models::File>>>,
|
||||
quick_check: bool,
|
||||
) -> UpdatePathResult {
|
||||
debug!("Processing: {:?}", path);
|
||||
|
||||
|
@ -281,11 +291,11 @@ fn process_directory_entry(
|
|||
let existing_file = existing_file.clone();
|
||||
drop(existing_files_read);
|
||||
|
||||
if size == existing_file.size {
|
||||
if !quick_check || size == existing_file.size {
|
||||
let same_mtime = mtime.is_some() && mtime == existing_file.mtime;
|
||||
let mut same_hash = false;
|
||||
|
||||
if !same_mtime {
|
||||
if !quick_check || !same_mtime {
|
||||
file_hash = Some(path.hash()?);
|
||||
same_hash = file_hash.as_ref().unwrap() == &existing_file.hash;
|
||||
}
|
||||
|
@ -456,7 +466,16 @@ mod test {
|
|||
use tempfile::TempDir;
|
||||
|
||||
#[test]
|
||||
fn test_rescan() {
|
||||
fn test_rescan_quick() {
|
||||
_test_rescan(true)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rescan_full() {
|
||||
_test_rescan(false)
|
||||
}
|
||||
|
||||
fn _test_rescan(quick: bool) {
|
||||
// Prepare temporary filesystem structure
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
|
||||
|
@ -483,7 +502,7 @@ mod test {
|
|||
|
||||
// Initial scan
|
||||
let rescan_result =
|
||||
rescan_vault_inner(&open_result.db, job_container.clone(), job_id, true);
|
||||
rescan_vault_inner(&open_result.db, job_container.clone(), job_id, quick, true);
|
||||
|
||||
assert!(rescan_result.is_ok());
|
||||
let rescan_result = rescan_result.unwrap();
|
||||
|
@ -495,7 +514,7 @@ mod test {
|
|||
// Modification-less rescan
|
||||
|
||||
let rescan_result =
|
||||
rescan_vault_inner(&open_result.db, job_container.clone(), job_id, false);
|
||||
rescan_vault_inner(&open_result.db, job_container.clone(), job_id, quick, false);
|
||||
|
||||
assert!(rescan_result.is_ok());
|
||||
let rescan_result = rescan_result.unwrap();
|
||||
|
@ -508,7 +527,8 @@ mod test {
|
|||
|
||||
std::fs::remove_file(temp_dir.path().join("hello-world.txt")).unwrap();
|
||||
|
||||
let rescan_result = rescan_vault_inner(&open_result.db, job_container, job_id, false);
|
||||
let rescan_result =
|
||||
rescan_vault_inner(&open_result.db, job_container, job_id, quick, false);
|
||||
|
||||
assert!(rescan_result.is_ok());
|
||||
let rescan_result = rescan_result.unwrap();
|
||||
|
|
|
@ -193,7 +193,7 @@ fn main() -> Result<()> {
|
|||
|
||||
if !matches.is_present("NO_INITIAL_UPDATE") {
|
||||
info!("Running initial update...");
|
||||
actix::spawn(filesystem::rescan_vault(upend, job_container, true));
|
||||
actix::spawn(filesystem::rescan_vault(upend, job_container, false, true));
|
||||
}
|
||||
|
||||
#[cfg(feature = "desktop")]
|
||||
|
|
|
@ -363,11 +363,20 @@ pub async fn list_hier_roots(state: web::Data<State>) -> Result<HttpResponse, Er
|
|||
Ok(HttpResponse::Ok().json(result.as_hash().map_err(ErrorInternalServerError)?))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct RescanRequest {
|
||||
full: Option<String>,
|
||||
}
|
||||
|
||||
#[post("/api/refresh")]
|
||||
pub async fn api_refresh(state: web::Data<State>) -> Result<HttpResponse, Error> {
|
||||
pub async fn api_refresh(
|
||||
state: web::Data<State>,
|
||||
web::Query(query): web::Query<RescanRequest>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
actix::spawn(crate::filesystem::rescan_vault(
|
||||
state.upend.clone(),
|
||||
state.job_container.clone(),
|
||||
query.full.is_none(),
|
||||
false,
|
||||
));
|
||||
Ok(HttpResponse::Ok().finish())
|
||||
|
|
Loading…
Reference in New Issue