mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-01-22 19:27:27 +01:00
handle the case of a queue of zero elements
This commit is contained in:
parent
e7704f1fc1
commit
8127c9a115
@ -47,14 +47,21 @@ impl SearchQueue {
|
||||
loop {
|
||||
tokio::select! {
|
||||
search_request = receive_new_searches.recv() => {
|
||||
// this unwrap is safe because we're sure the `SearchQueue` still lives somewhere in actix-web
|
||||
let search_request = search_request.unwrap();
|
||||
if searches_running < usize::from(parallelism) && queue.is_empty() {
|
||||
searches_running += 1;
|
||||
// if the search requests die it's not a hard error on our side
|
||||
let _ = search_request.send(Permit { sender: sender.clone() });
|
||||
continue;
|
||||
}
|
||||
if queue.len() >= capacity {
|
||||
} else if capacity == 0 {
|
||||
// in the very specific case where we have a capacity of zero
|
||||
// we must refuse the request straight away without going through
|
||||
// the queue stuff.
|
||||
drop(search_request);
|
||||
continue;
|
||||
|
||||
} else if queue.len() >= capacity {
|
||||
let remove = rng.gen_range(0..queue.len());
|
||||
let thing = queue.swap_remove(remove); // this will drop the channel and notify the search that it won't be processed
|
||||
drop(thing);
|
||||
|
@ -131,3 +131,40 @@ async fn search_request_crashes_while_holding_permits() {
|
||||
.expect("I should get a permit straight away")
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn works_with_capacity_of_zero() {
|
||||
let queue = Arc::new(SearchQueue::new(0, NonZeroUsize::new(1).unwrap()));
|
||||
|
||||
// First, use the whole capacity of the
|
||||
let permit1 = tokio::time::timeout(Duration::from_secs(1), queue.try_get_search_permit())
|
||||
.await
|
||||
.expect("I should get a permit straight away")
|
||||
.unwrap();
|
||||
|
||||
// then we should get an error if we try to register a second search request.
|
||||
let permit2 = tokio::time::timeout(Duration::from_secs(1), queue.try_get_search_permit())
|
||||
.await
|
||||
.expect("I should get a result straight away");
|
||||
|
||||
let err = meilisearch_types::error::ResponseError::from(permit2.unwrap_err());
|
||||
let http_response = err.error_response();
|
||||
snapshot!(format!("{:?}", http_response.headers()), @r###"HeaderMap { inner: {"content-type": Value { inner: ["application/json"] }, "retry-after": Value { inner: ["10"] }} }"###);
|
||||
|
||||
let err = serde_json::to_string_pretty(&err).unwrap();
|
||||
snapshot!(err, @r###"
|
||||
{
|
||||
"message": "Too many search requests running at the same time: 0. Retry after 10s.",
|
||||
"code": "too_many_search_requests",
|
||||
"type": "system",
|
||||
"link": "https://docs.meilisearch.com/errors#too_many_search_requests"
|
||||
}
|
||||
"###);
|
||||
|
||||
drop(permit1);
|
||||
// After dropping the first permit we should be able to get a new permit
|
||||
let _permit3 = tokio::time::timeout(Duration::from_secs(1), queue.try_get_search_permit())
|
||||
.await
|
||||
.expect("I should get a permit straight away")
|
||||
.unwrap();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user