fix: address reviewer feedback — regex OnceLock and restore tick rate

- Compile whitespace regex once via OnceLock instead of on every
  non-success response; makes format_error_body infallible (String
  return, no Result) eliminating the only practical failure mode
- Revert default tick rate from 100ms back to 50ms to preserve the
  existing 20-second Servarr poll cadence (tick_until_poll=400 × 50ms);
  the recv() change is the real CPU fix — the tick rate change was
  unnecessary and silently halved the data refresh rate
- Keep MANAGARR_TICK_RATE_MS as opt-in override; note that tuning it
  proportionally stretches the poll interval alongside the tick rate
This commit is contained in:
Jonathan McCumber
2026-06-28 13:00:16 -05:00
parent 6c41e0704e
commit a72b2991fd
2 changed files with 12 additions and 13 deletions
+5 -8
View File
@@ -19,7 +19,7 @@ pub struct Events {
rx: Receiver<InputEvent<Key>>,
}
const DEFAULT_TICK_RATE_MS: u64 = 100;
const DEFAULT_TICK_RATE_MS: u64 = 50;
fn configured_tick_rate_ms_from(raw: Option<&str>) -> u64 {
raw
@@ -78,18 +78,15 @@ mod tests {
use super::*;
#[test]
fn defaults_to_a_slower_idle_tick_rate() {
assert_eq!(DEFAULT_TICK_RATE_MS, 100);
assert_eq!(configured_tick_rate_ms_from(None), 100);
fn defaults_to_original_tick_rate() {
assert_eq!(DEFAULT_TICK_RATE_MS, 50);
assert_eq!(configured_tick_rate_ms_from(None), 50);
}
#[test]
fn parses_positive_tick_rates_and_rejects_invalid_values() {
assert_eq!(configured_tick_rate_ms_from(Some("250")), 250);
assert_eq!(
configured_tick_rate_ms_from(Some("0")),
DEFAULT_TICK_RATE_MS
);
assert_eq!(configured_tick_rate_ms_from(Some("0")), DEFAULT_TICK_RATE_MS);
assert_eq!(
configured_tick_rate_ms_from(Some("abc")),
DEFAULT_TICK_RATE_MS
+7 -5
View File
@@ -1,11 +1,13 @@
use std::fmt::Debug;
use std::sync::Arc;
use std::sync::{Arc, OnceLock};
use anyhow::{Result, anyhow};
use async_trait::async_trait;
use lidarr_network::LidarrEvent;
use log::{debug, error, warn};
use regex::Regex;
static WHITESPACE_RE: OnceLock<Regex> = OnceLock::new();
use reqwest::{Client, RequestBuilder};
use serde::Serialize;
use serde::de::DeserializeOwned;
@@ -144,7 +146,7 @@ impl<'a, 'b> Network<'a, 'b> {
} else {
let status = response.status();
let response_body = response.text().await.unwrap_or_default();
let error_body = format_error_body(&response_body)?;
let error_body = format_error_body(&response_body);
error!("Request failed. Received {status} response code with body: {response_body}");
self.app.lock().await.handle_error(anyhow!("Request failed. Received {status} response code with body: {error_body}"));
@@ -277,8 +279,8 @@ impl<'a, 'b> Network<'a, 'b> {
}
}
fn format_error_body(response_body: &str) -> Result<String> {
let whitespace_regex = Regex::new(r"\s+")?;
fn format_error_body(response_body: &str) -> String {
let re = WHITESPACE_RE.get_or_init(|| Regex::new(r"\s+").unwrap());
let body = serde_json::from_str::<Value>(response_body)
.ok()
.and_then(|value| {
@@ -291,7 +293,7 @@ fn format_error_body(response_body: &str) -> Result<String> {
})
.unwrap_or_else(|| response_body.replace('\n', " "));
Ok(whitespace_regex.replace_all(&body, " ").to_string())
re.replace_all(&body, " ").to_string()
}
#[derive(Clone, Copy, Debug, Display, PartialEq, Eq)]