From b2e4e157c3021e88e621573bafdeb223de26af82 Mon Sep 17 00:00:00 2001 From: Miguel Palhas Date: Sat, 22 Aug 2026 20:33:39 +0100 Subject: [PATCH] fix(api): reject full action queues --- crates/arr-api/src/movies.rs | 21 +++++++++++++++++++-- crates/arr-api/src/state.rs | 6 +++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/crates/arr-api/src/movies.rs b/crates/arr-api/src/movies.rs index f89a585..2c352dc 100644 --- a/crates/arr-api/src/movies.rs +++ b/crates/arr-api/src/movies.rs @@ -332,7 +332,6 @@ pub async fn search( } state .send_movie_command(MovieCommand::Search { movie_id: id }) - .await .map_err(|_| ApiError::Unavailable)?; Ok((StatusCode::ACCEPTED, Json(Accepted { accepted: true }))) } @@ -383,7 +382,6 @@ pub async fn grab( movie_id, release_id, }) - .await .map_err(|_| ApiError::Unavailable)?; Ok((StatusCode::ACCEPTED, Json(Accepted { accepted: true }))) } @@ -537,6 +535,25 @@ mod tests { ); } + #[tokio::test] + async fn a_full_action_queue_returns_service_unavailable() { + let (_dir, state, base) = application().await; + let movie = add_movie(&base, 693_134, 2).await; + let movie_id = movie["id"].as_i64().expect("id"); + for _ in 0..64 { + state + .send_movie_command(MovieCommand::Search { movie_id }) + .expect("queue has capacity"); + } + + let response = reqwest::Client::new() + .post(format!("{base}/api/movies/{movie_id}/search")) + .send() + .await + .expect("search"); + assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE); + } + #[tokio::test] async fn attention_queues_follow_search_and_failure_state() { let (_dir, state, base) = application().await; diff --git a/crates/arr-api/src/state.rs b/crates/arr-api/src/state.rs index 0567a16..0030cd5 100644 --- a/crates/arr-api/src/state.rs +++ b/crates/arr-api/src/state.rs @@ -124,10 +124,10 @@ impl AppState { self.database.as_ref() } - pub(crate) async fn send_movie_command( + pub(crate) fn send_movie_command( &self, command: MovieCommand, - ) -> Result<(), mpsc::error::SendError> { - self.movie_commands.send(command).await + ) -> Result<(), mpsc::error::TrySendError> { + self.movie_commands.try_send(command) } }