diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 5a1d5992a6..b85d0b9b40 100644 --- a/crates/search/src/project_search.rs +++ b/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>, _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; } } diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 92b11f00d1..efcc1ba242 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -112,7 +112,7 @@ pub enum SemanticIndexStatus { Indexed, Indexing { remaining_files: usize, - rate_limit_expiration_time: Option, + rate_limit_expiry: Option, }, } @@ -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 {