move cx notify observe for rate_limit_expiry into ProjectState in the semantic index

KCaverly and Antonio created

Co-authored-by: Antonio <antonio@zed.dev>

Change summary

crates/search/src/project_search.rs         | 31 ++++++++++++++++++----
crates/semantic_index/src/semantic_index.rs | 21 +++-----------
2 files changed, 30 insertions(+), 22 deletions(-)

Detailed changes

crates/search/src/project_search.rs 🔗

@@ -34,7 +34,7 @@ use std::{
     ops::{Not, Range},
     path::PathBuf,
     sync::Arc,
-    time::SystemTime,
+    time::{Duration, SystemTime},
 };
 use util::ResultExt as _;
 use workspace::{
@@ -131,6 +131,7 @@ pub struct ProjectSearchView {
 
 struct SemanticState {
     index_status: SemanticIndexStatus,
+    maintain_rate_limit: Option<Task<()>>,
     _subscription: Subscription,
 }
 
@@ -322,14 +323,14 @@ impl View for ProjectSearchView {
                     SemanticIndexStatus::Indexed => Some("Indexing complete".to_string()),
                     SemanticIndexStatus::Indexing {
                         remaining_files,
-                        rate_limit_expiration_time,
+                        rate_limit_expiry,
                     } => {
                         if remaining_files == 0 {
                             Some(format!("Indexing..."))
                         } else {
-                            if let Some(rate_limit_expiration_time) = rate_limit_expiration_time {
+                            if let Some(rate_limit_expiry) = rate_limit_expiry {
                                 if let Ok(remaining_seconds) =
-                                    rate_limit_expiration_time.duration_since(SystemTime::now())
+                                    rate_limit_expiry.duration_since(SystemTime::now())
                                 {
                                     Some(format!(
                                         "Remaining files to index (rate limit resets in {}s): {}",
@@ -669,9 +670,10 @@ impl ProjectSearchView {
 
             self.semantic_state = Some(SemanticState {
                 index_status: semantic_index.read(cx).status(&project),
+                maintain_rate_limit: None,
                 _subscription: cx.observe(&semantic_index, Self::semantic_index_changed),
             });
-            cx.notify();
+            self.semantic_index_changed(semantic_index, cx);
         }
     }
 
@@ -682,8 +684,25 @@ impl ProjectSearchView {
     ) {
         let project = self.model.read(cx).project.clone();
         if let Some(semantic_state) = self.semantic_state.as_mut() {
-            semantic_state.index_status = semantic_index.read(cx).status(&project);
             cx.notify();
+            semantic_state.index_status = semantic_index.read(cx).status(&project);
+            if let SemanticIndexStatus::Indexing {
+                rate_limit_expiry: Some(_),
+                ..
+            } = &semantic_state.index_status
+            {
+                if semantic_state.maintain_rate_limit.is_none() {
+                    semantic_state.maintain_rate_limit =
+                        Some(cx.spawn(|this, mut cx| async move {
+                            loop {
+                                cx.background().timer(Duration::from_secs(1)).await;
+                                this.update(&mut cx, |_, cx| cx.notify()).log_err();
+                            }
+                        }));
+                    return;
+                }
+            }
+            semantic_state.maintain_rate_limit = None;
         }
     }
 

crates/semantic_index/src/semantic_index.rs 🔗

@@ -112,7 +112,7 @@ pub enum SemanticIndexStatus {
     Indexed,
     Indexing {
         remaining_files: usize,
-        rate_limit_expiration_time: Option<SystemTime>,
+        rate_limit_expiry: Option<SystemTime>,
     },
 }
 
@@ -232,20 +232,9 @@ impl ProjectState {
             _observe_pending_file_count: cx.spawn_weak({
                 let mut pending_file_count_rx = pending_file_count_rx.clone();
                 |this, mut cx| async move {
-                    loop {
-                        let mut timer = cx.background().timer(Duration::from_millis(350)).fuse();
-                        let mut pending_file_count = pending_file_count_rx.next().fuse();
-                        futures::select_biased! {
-                            _ = pending_file_count => {
-                                if let Some(this) = this.upgrade(&cx) {
-                                    this.update(&mut cx, |_, cx| cx.notify());
-                                }
-                            },
-                            _ = timer => {
-                                if let Some(this) = this.upgrade(&cx) {
-                                    this.update(&mut cx, |_, cx| cx.notify());
-                                }
-                            }
+                    while let Some(_) = pending_file_count_rx.next().await {
+                        if let Some(this) = this.upgrade(&cx) {
+                            this.update(&mut cx, |_, cx| cx.notify());
                         }
                     }
                 }
@@ -304,7 +293,7 @@ impl SemanticIndex {
             } else {
                 SemanticIndexStatus::Indexing {
                     remaining_files: project_state.pending_file_count_rx.borrow().clone(),
-                    rate_limit_expiration_time: self.embedding_provider.rate_limit_expiration(),
+                    rate_limit_expiry: self.embedding_provider.rate_limit_expiration(),
                 }
             }
         } else {