mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-26 23:04:26 +01:00
feat: Introduce a way to enable or disable query timeouts
This commit is contained in:
parent
67302d09f3
commit
9c5ec110e5
@ -185,6 +185,7 @@ pub struct QueryBuilder<'c, S, FI = fn(DocumentId) -> bool> {
|
|||||||
criteria: Criteria<'c>,
|
criteria: Criteria<'c>,
|
||||||
searchable_attrs: Option<ReorderedAttrs>,
|
searchable_attrs: Option<ReorderedAttrs>,
|
||||||
filter: Option<FI>,
|
filter: Option<FI>,
|
||||||
|
fetch_timeout: Option<Duration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c, S> QueryBuilder<'c, S, fn(DocumentId) -> bool> {
|
impl<'c, S> QueryBuilder<'c, S, fn(DocumentId) -> bool> {
|
||||||
@ -193,7 +194,7 @@ impl<'c, S> QueryBuilder<'c, S, fn(DocumentId) -> bool> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_criteria(store: S, criteria: Criteria<'c>) -> Self {
|
pub fn with_criteria(store: S, criteria: Criteria<'c>) -> Self {
|
||||||
QueryBuilder { store, criteria, searchable_attrs: None, filter: None }
|
QueryBuilder { store, criteria, searchable_attrs: None, filter: None, fetch_timeout: None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,9 +208,14 @@ impl<'c, S, FI> QueryBuilder<'c, S, FI>
|
|||||||
criteria: self.criteria,
|
criteria: self.criteria,
|
||||||
searchable_attrs: self.searchable_attrs,
|
searchable_attrs: self.searchable_attrs,
|
||||||
filter: Some(function),
|
filter: Some(function),
|
||||||
|
fetch_timeout: self.fetch_timeout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_fetch_timeout(self, timeout: Duration) -> QueryBuilder<'c, S, FI> {
|
||||||
|
QueryBuilder { fetch_timeout: Some(timeout), ..self }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn with_distinct<F, K>(self, function: F, size: usize) -> DistinctQueryBuilder<'c, S, FI, F>
|
pub fn with_distinct<F, K>(self, function: F, size: usize) -> DistinctQueryBuilder<'c, S, FI, F>
|
||||||
where F: Fn(DocumentId) -> Option<K>,
|
where F: Fn(DocumentId) -> Option<K>,
|
||||||
K: Hash + Eq,
|
K: Hash + Eq,
|
||||||
@ -226,6 +232,7 @@ impl<'c, S, FI> QueryBuilder<'c, S, FI>
|
|||||||
fn multiword_rewrite_matches(
|
fn multiword_rewrite_matches(
|
||||||
mut matches: Vec<(DocumentId, TmpMatch)>,
|
mut matches: Vec<(DocumentId, TmpMatch)>,
|
||||||
query_enhancer: &QueryEnhancer,
|
query_enhancer: &QueryEnhancer,
|
||||||
|
timeout: Option<Duration>,
|
||||||
) -> SetBuf<(DocumentId, TmpMatch)>
|
) -> SetBuf<(DocumentId, TmpMatch)>
|
||||||
{
|
{
|
||||||
let mut padded_matches = Vec::with_capacity(matches.len());
|
let mut padded_matches = Vec::with_capacity(matches.len());
|
||||||
@ -240,7 +247,7 @@ fn multiword_rewrite_matches(
|
|||||||
for same_document_attribute in matches.linear_group_by_key(|(id, m)| (*id, m.attribute)) {
|
for same_document_attribute in matches.linear_group_by_key(|(id, m)| (*id, m.attribute)) {
|
||||||
|
|
||||||
let elapsed = start.elapsed();
|
let elapsed = start.elapsed();
|
||||||
if elapsed > Duration::from_millis(10) {
|
if timeout.map_or(false, |timeout| elapsed > timeout) {
|
||||||
info!("abort multiword rewrite after {:.2?}", elapsed);
|
info!("abort multiword rewrite after {:.2?}", elapsed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -341,6 +348,7 @@ where S: Store + Sync,
|
|||||||
let (automatons, query_enhancer) = generate_automatons(query, &self.store)?;
|
let (automatons, query_enhancer) = generate_automatons(query, &self.store)?;
|
||||||
let searchables = self.searchable_attrs.as_ref();
|
let searchables = self.searchable_attrs.as_ref();
|
||||||
let store = &self.store;
|
let store = &self.store;
|
||||||
|
let fetch_timeout = &self.fetch_timeout;
|
||||||
|
|
||||||
rayon::scope(move |s| {
|
rayon::scope(move |s| {
|
||||||
enum Error<E> {
|
enum Error<E> {
|
||||||
@ -351,10 +359,10 @@ where S: Store + Sync,
|
|||||||
let mut matches = Vec::new();
|
let mut matches = Vec::new();
|
||||||
let mut highlights = Vec::new();
|
let mut highlights = Vec::new();
|
||||||
|
|
||||||
let recv_end_time = Instant::now() + Duration::from_millis(30);
|
let recv_end_time = fetch_timeout.map(|d| Instant::now() + d * 75 / 100);
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
let (sender, receiver) = crossbeam_channel::bounded(10);
|
let (sender, receiver) = crossbeam_channel::unbounded();
|
||||||
|
|
||||||
s.spawn(move |_| {
|
s.spawn(move |_| {
|
||||||
let result = automatons
|
let result = automatons
|
||||||
@ -417,6 +425,11 @@ where S: Store + Sync,
|
|||||||
});
|
});
|
||||||
|
|
||||||
let iter = receiver.recv().into_iter().chain(iter::from_fn(|| {
|
let iter = receiver.recv().into_iter().chain(iter::from_fn(|| {
|
||||||
|
let recv_end_time = match recv_end_time {
|
||||||
|
Some(time) => time,
|
||||||
|
None => return receiver.recv().ok(),
|
||||||
|
};
|
||||||
|
|
||||||
match recv_end_time.checked_duration_since(Instant::now()) {
|
match recv_end_time.checked_duration_since(Instant::now()) {
|
||||||
Some(timeout) => receiver.recv_timeout(timeout).ok(),
|
Some(timeout) => receiver.recv_timeout(timeout).ok(),
|
||||||
None => None,
|
None => None,
|
||||||
@ -434,7 +447,8 @@ where S: Store + Sync,
|
|||||||
info!("{} total matches to rewrite", matches.len());
|
info!("{} total matches to rewrite", matches.len());
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let matches = multiword_rewrite_matches(matches, &query_enhancer);
|
let timeout = fetch_timeout.map(|d| d * 25 / 100);
|
||||||
|
let matches = multiword_rewrite_matches(matches, &query_enhancer, timeout);
|
||||||
info!("multiword rewrite took {:.2?}", start.elapsed());
|
info!("multiword rewrite took {:.2?}", start.elapsed());
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
@ -526,7 +540,15 @@ impl<'c, I, FI, FD> DistinctQueryBuilder<'c, I, FI, FD>
|
|||||||
DistinctQueryBuilder {
|
DistinctQueryBuilder {
|
||||||
inner: self.inner.with_filter(function),
|
inner: self.inner.with_filter(function),
|
||||||
function: self.function,
|
function: self.function,
|
||||||
size: self.size
|
size: self.size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_fetch_timeout(self, timeout: Duration) -> DistinctQueryBuilder<'c, I, FI, FD> {
|
||||||
|
DistinctQueryBuilder {
|
||||||
|
inner: self.inner.with_fetch_timeout(timeout),
|
||||||
|
function: self.function,
|
||||||
|
size: self.size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ impl<'a> SynonymsAddition<'a> {
|
|||||||
|
|
||||||
// update the "consistent" view of the Index
|
// update the "consistent" view of the Index
|
||||||
let words = main.words_set()?.unwrap_or_default();
|
let words = main.words_set()?.unwrap_or_default();
|
||||||
let ranked_map = lease_inner.ranked_map.clone();;
|
let ranked_map = lease_inner.ranked_map.clone();
|
||||||
let schema = lease_inner.schema.clone();
|
let schema = lease_inner.schema.clone();
|
||||||
let raw = lease_inner.raw.clone();
|
let raw = lease_inner.raw.clone();
|
||||||
lease_inner.raw.compact();
|
lease_inner.raw.compact();
|
||||||
|
@ -159,7 +159,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
Ok(query) => {
|
Ok(query) => {
|
||||||
let start_total = Instant::now();
|
let start_total = Instant::now();
|
||||||
|
|
||||||
let builder = index.query_builder();
|
let builder = index.query_builder().with_fetch_timeout(Duration::from_millis(40));
|
||||||
let documents = builder.query(&query, 0..opt.number_results)?;
|
let documents = builder.query(&query, 0..opt.number_results)?;
|
||||||
|
|
||||||
let mut retrieve_duration = Duration::default();
|
let mut retrieve_duration = Duration::default();
|
||||||
|
Loading…
Reference in New Issue
Block a user