aboutsummaryrefslogtreecommitdiff
path: root/server/src/import.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/import.rs')
-rw-r--r--server/src/import.rs43
1 files changed, 26 insertions, 17 deletions
diff --git a/server/src/import.rs b/server/src/import.rs
index c8f4f10..b306332 100644
--- a/server/src/import.rs
+++ b/server/src/import.rs
@@ -5,27 +5,38 @@
*/
use crate::{database::Database, CONF};
use anyhow::{bail, Context, Ok};
+use async_recursion::async_recursion;
use jellycommon::Node;
use log::info;
-use std::{ffi::OsStr, fs::File, os::unix::prelude::OsStrExt, path::PathBuf};
+use std::{ffi::OsStr, fs::File, os::unix::prelude::OsStrExt, path::PathBuf, sync::LazyLock};
+use tokio::sync::Semaphore;
-pub fn import(db: &Database) -> anyhow::Result<()> {
+static IMPORT_SEM: LazyLock<Semaphore> = LazyLock::new(|| Semaphore::new(1));
+
+pub async fn import(db: &Database) -> anyhow::Result<()> {
info!("clearing node tree");
- db.node.clear()?;
- info!("importing...");
- import_path(CONF.library_path.clone(), db, None).context("indexing")?;
+ let permit = IMPORT_SEM.try_acquire()?;
+ {
+ db.node.clear()?;
+ info!("importing...");
+ import_path(CONF.library_path.clone(), db, None)
+ .await
+ .context("indexing")?;
+ info!("import completed");
+ }
+ drop(permit);
Ok(())
}
-pub fn import_path(
+#[async_recursion]
+pub async fn import_path(
path: PathBuf,
db: &Database,
parent: Option<String>,
) -> anyhow::Result<Vec<String>> {
if path.is_dir() {
let mpath = path.join("directory.json");
- let children = path.read_dir()?.filter_map(|e| {
- let e = e.unwrap();
+ let children_paths = path.read_dir()?.map(Result::unwrap).filter_map(|e| {
if e.path().extension() == Some(&OsStr::from_bytes(b"jelly"))
|| e.metadata().unwrap().is_dir()
{
@@ -35,23 +46,21 @@ pub fn import_path(
}
});
let identifier = path.file_name().unwrap().to_str().unwrap().to_string();
- let children = children
- .map(|e| import_path(e, db, Some(identifier.clone())))
- .collect::<anyhow::Result<Vec<_>>>()?
- .into_iter()
- .flatten()
- .collect();
+ let mut children_ids = Vec::new();
+ for p in children_paths {
+ children_ids.extend(import_path(p, db, Some(identifier.clone())).await?)
+ }
if mpath.exists() {
let mut data: Node =
serde_json::from_reader(File::open(mpath).context("metadata missing")?)?;
- data.public.children = children;
+ data.public.children = children_ids;
data.public.parent = parent;
info!("insert {identifier}");
db.node.insert(&identifier, &data)?;
Ok(vec![identifier])
} else {
- Ok(children)
+ Ok(children_ids)
}
} else if path.is_file() {
info!("loading item {path:?}");
@@ -65,7 +74,7 @@ pub fn import_path(
.strip_suffix(".jelly")
.unwrap()
.to_string();
-
+
info!("insert {identifier}");
data.public.parent = parent;
db.node.insert(&identifier, &data)?;