add explicit quick_check/disable_synchronous flags, ?full param to rescan endpoint

feat/vaults
Tomáš Mládek 2022-01-31 17:26:31 +01:00
parent 466f870d6f
commit 9c940e7c23
3 changed files with 41 additions and 12 deletions

View File

@ -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();

View File

@ -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")]

View File

@ -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())