aboutsummaryrefslogtreecommitdiff
path: root/server/src/import.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-09-24 19:19:21 +0200
committermetamuffin <metamuffin@disroot.org>2023-09-24 19:19:21 +0200
commit11a7ad0a6f66d692f1e9e002bb73ea6f737c84bb (patch)
treefe5256af49d84d9fef636d1862aab8956445b087 /server/src/import.rs
parent6b3ebbc1dd73382d81252778eac04cba6955584a (diff)
downloadjellything-11a7ad0a6f66d692f1e9e002bb73ea6f737c84bb.tar
jellything-11a7ad0a6f66d692f1e9e002bb73ea6f737c84bb.tar.bz2
jellything-11a7ad0a6f66d692f1e9e002bb73ea6f737c84bb.tar.zst
flat import (untested) + parallel fed download
Diffstat (limited to 'server/src/import.rs')
-rw-r--r--server/src/import.rs84
1 files changed, 51 insertions, 33 deletions
diff --git a/server/src/import.rs b/server/src/import.rs
index ccf5274..8908c00 100644
--- a/server/src/import.rs
+++ b/server/src/import.rs
@@ -112,7 +112,7 @@ pub async fn import_path(
.await
.context("creating session")?;
- import_remote(io, db, &session, &identifier, parent)
+ import_remote(io, db, &session, identifier.clone(), parent)
.await
.context("federated import")?;
} else {
@@ -126,14 +126,17 @@ pub async fn import_path(
}
}
+static SEM_REMOTE_IMPORT: LazyLock<Semaphore> = LazyLock::new(|| Semaphore::new(16));
+
#[async_recursion]
async fn import_remote(
opts: RemoteImportOptions,
db: &Database,
session: &Session,
- identifier: &String,
+ identifier: String,
parent: Option<String>,
) -> anyhow::Result<()> {
+ let _permit = SEM_REMOTE_IMPORT.acquire().await.unwrap();
info!("loading federated node {identifier:?}");
let node = session
.node(&opts.id)
@@ -143,40 +146,55 @@ async fn import_remote(
let poster = cache_federation_asset(session, &opts.id, "poster").await?;
let backdrop = cache_federation_asset(session, &opts.id, "backdrop").await?;
- let mut node = Node {
- public: node,
- private: NodePrivate {
- backdrop: Some(AssetLocation::Cache(backdrop)),
- poster: Some(AssetLocation::Cache(poster)),
- import: None,
- id: None,
- source: Some(MediaSource::Remote {
- host: opts.host.clone(),
- remote_id: opts.id.clone(),
- }),
- },
- };
+ drop(_permit);
- for c in &mut node.public.children {
- let prefixed = format!("{}{c}", opts.prefix.clone().unwrap_or(String::new()));
- import_remote(
- RemoteImportOptions {
- id: c.to_owned(),
- ..opts.clone()
+ let child_parent = if opts.flatten {
+ parent
+ } else {
+ let mut node = Node {
+ public: node.clone(),
+ private: NodePrivate {
+ backdrop: Some(AssetLocation::Cache(backdrop)),
+ poster: Some(AssetLocation::Cache(poster)),
+ import: None,
+ id: None,
+ source: Some(MediaSource::Remote {
+ host: opts.host.clone(),
+ remote_id: opts.id.clone(),
+ }),
},
- db,
- session,
- &prefixed,
- Some(opts.id.clone()),
- )
- .await?;
- *c = prefixed;
- }
+ };
+ node.public.parent = parent;
+ node.public.federated = Some(opts.host.clone());
+ node.public
+ .children
+ .iter_mut()
+ .for_each(|c| *c = format!("{}{c}", opts.prefix.clone().unwrap_or(String::new())));
+
+ debug!("adding {identifier}");
+ db.node.insert(&identifier, &node)?;
+ Some(opts.id.clone())
+ };
+
+ let mut children: FuturesUnordered<_> = node
+ .children
+ .iter()
+ .map(|c| {
+ let prefixed = format!("{}{c}", opts.prefix.clone().unwrap_or(String::new()));
+ import_remote(
+ RemoteImportOptions {
+ id: c.to_owned(),
+ ..opts.clone()
+ },
+ db,
+ session,
+ prefixed,
+ child_parent.clone(),
+ )
+ })
+ .collect();
- node.public.parent = parent;
- node.public.federated = Some(opts.host.clone());
- debug!("adding {identifier}");
- db.node.insert(identifier, &node)?;
+ while let Some(_) = children.next().await {}
Ok(())
}