فهرست منبع

fud: move `lookup_nodes` calls (from `fetch_seeders` and `fetch_file_metadata`) to `handle_get`

epiphany 1 سال پیش
والد
کامیت
ac01c8a0a2
3فایلهای تغییر یافته به همراه31 افزوده شده و 27 حذف شده
  1. 21 23
      bin/fud/fud/src/main.rs
  2. 8 2
      bin/fud/fud/src/rpc.rs
  3. 2 2
      bin/fud/fud/src/tasks.rs

+ 21 - 23
bin/fud/fud/src/main.rs

@@ -144,8 +144,8 @@ pub struct Fud {
 
     get_tx: channel::Sender<(u16, blake3::Hash, PathBuf, Result<()>)>,
     get_rx: channel::Receiver<(u16, blake3::Hash, PathBuf, Result<()>)>,
-    file_fetch_tx: channel::Sender<(blake3::Hash, Result<()>)>,
-    file_fetch_rx: channel::Receiver<(blake3::Hash, Result<()>)>,
+    file_fetch_tx: channel::Sender<(Vec<DhtNode>, blake3::Hash, Result<()>)>,
+    file_fetch_rx: channel::Receiver<(Vec<DhtNode>, blake3::Hash, Result<()>)>,
     file_fetch_end_tx: channel::Sender<(blake3::Hash, Result<()>)>,
     file_fetch_end_rx: channel::Receiver<(blake3::Hash, Result<()>)>,
 
@@ -334,17 +334,16 @@ impl Fud {
         Ok(seeding_resources)
     }
 
-    /// Query nodes close to `key` to find the seeders
-    async fn fetch_seeders(&self, key: &blake3::Hash) -> HashSet<DhtRouterItem> {
-        let closest_nodes = self.lookup_nodes(key).await; // Find the `k` closest nodes
-        if closest_nodes.is_err() {
-            return HashSet::new();
-        }
-
+    /// Query `nodes` to find the seeders for `key`
+    async fn fetch_seeders(
+        &self,
+        nodes: &Vec<DhtNode>,
+        key: &blake3::Hash,
+    ) -> HashSet<DhtRouterItem> {
         let mut seeders: HashSet<DhtRouterItem> = HashSet::new();
 
-        for node in closest_nodes.unwrap() {
-            let channel = match self.get_channel(&node).await {
+        for node in nodes {
+            let channel = match self.get_channel(node).await {
                 Ok(channel) => channel,
                 Err(e) => {
                     warn!(target: "fud::fetch_seeders()", "Could not get a channel for node {}: {}", hash_to_string(&node.id), e);
@@ -521,21 +520,20 @@ impl Fud {
         Ok(())
     }
 
-    /// Fetch a single file metadata from the network.
+    /// Fetch a single file metadata from `nodes`.
     /// If the file is smaller than a single chunk then the chunk is returned.
-    /// 1. Lookup nodes close to the key
-    /// 2. Request seeders for the file from those nodes
-    /// 3. Request the file from the seeders
-    async fn fetch_file_metadata(&self, file_hash: blake3::Hash) -> Option<FetchReply> {
+    /// 1. Request seeders for the file from those nodes
+    /// 2. Request the file from the seeders
+    async fn fetch_file_metadata(
+        &self,
+        nodes: Vec<DhtNode>,
+        file_hash: blake3::Hash,
+    ) -> Option<FetchReply> {
         let mut queried_seeders: HashSet<blake3::Hash> = HashSet::new();
-        let closest_nodes = self.lookup_nodes(&file_hash).await; // 1
         let mut result: Option<FetchReply> = None;
-        if closest_nodes.is_err() {
-            return None
-        }
 
-        for node in closest_nodes.unwrap() {
-            // 2. Request list of seeders
+        for node in nodes {
+            // 1. Request list of seeders
             let channel = match self.get_channel(&node).await {
                 Ok(channel) => channel,
                 Err(e) => {
@@ -575,7 +573,7 @@ impl Fud {
 
             msg_subscriber.unsubscribe().await;
 
-            // 3. Request the file/chunk from the seeders
+            // 2. Request the file/chunk from the seeders
             while let Some(seeder) = seeders.pop() {
                 // Only query a seeder once
                 if queried_seeders.iter().any(|s| *s == seeder.node.id) {

+ 8 - 2
bin/fud/fud/src/rpc.rs

@@ -523,12 +523,15 @@ impl Fud {
             }))
             .await;
 
+        let mut closest_nodes = vec![];
+
         let chunked_file = match self.geode.get(file_hash).await {
             Ok(v) => v,
             Err(Error::GeodeNeedsGc) => todo!(),
             Err(Error::GeodeFileNotFound) => {
                 info!(target: "self::get()", "Requested file {} not found in Geode, triggering fetch", hash_to_string(file_hash));
-                self.file_fetch_tx.send((*file_hash, Ok(()))).await.unwrap();
+                closest_nodes = self.lookup_nodes(file_hash).await.unwrap_or_default();
+                self.file_fetch_tx.send((closest_nodes.clone(), *file_hash, Ok(()))).await.unwrap();
                 info!(target: "self::get()", "Waiting for background file fetch task...");
                 let (i_file_hash, status) = self.file_fetch_end_rx.recv().await.unwrap();
                 match status {
@@ -627,7 +630,10 @@ impl Fud {
             };
         }
 
-        let seeders = self.fetch_seeders(file_hash).await;
+        if closest_nodes.is_empty() {
+            closest_nodes = self.lookup_nodes(file_hash).await.unwrap_or_default();
+        }
+        let seeders = self.fetch_seeders(&closest_nodes, file_hash).await;
 
         // List missing chunks
         let mut missing_chunks = HashSet::new();

+ 2 - 2
bin/fud/fud/src/tasks.rs

@@ -47,10 +47,10 @@ pub enum FetchReply {
 pub async fn fetch_file_task(fud: Arc<Fud>) -> Result<()> {
     info!(target: "fud::fetch_file_task()", "Started background file fetch task");
     loop {
-        let (file_hash, _) = fud.file_fetch_rx.recv().await.unwrap();
+        let (nodes, file_hash, _) = fud.file_fetch_rx.recv().await.unwrap();
         info!(target: "fud::fetch_file_task()", "Fetching file {}", hash_to_string(&file_hash));
 
-        let result = fud.fetch_file_metadata(file_hash).await;
+        let result = fud.fetch_file_metadata(nodes, file_hash).await;
 
         match result {
             Some(reply) => {