mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-09-23 23:32:05 +00:00
perf: stop the sweep stealing worker wakeups, retry-free inline fetch
- queue: the lease-expiry sweep waited on the workers' `Notify`. `notify_one` stores a permit, so a sweep wakeup could consume the one meant for a worker, which then blocked on `notified()` (it only waits when the table looked empty, i.e. indefinitely) with a due row sitting there. The sweep now has its own notify, woken only by stop. - x-media: split fetch's retry loop into `fetch` (3 attempts, unchanged) and `fetch_once` (1 attempt); inline queries use the latter — the 800ms debounce plus 1s/2s backoffs were outlasting the answer window of the query. - send: chunk_media_items now moves items out of the input Vec instead of requiring `T: Clone` and copying every payload. fmt/clippy clean, 55 + 69 tests pass.
This commit is contained in:
@@ -375,10 +375,24 @@ pub async fn validate_all() -> Vec<(&'static str, String)> {
|
||||
/// are returned immediately; retrying them only wastes attempts against the
|
||||
/// source site.
|
||||
pub async fn fetch(url: &str) -> Result<Option<Fetched>, FetchError> {
|
||||
fetch_with_attempts(url, MAX_FETCH_ATTEMPTS).await
|
||||
}
|
||||
|
||||
/// [`fetch`] without the retry backoff (one attempt). For callers with a
|
||||
/// short deadline: an inline query's answer window is measured in seconds, so
|
||||
/// the 1s + 2s retry sleeps would outlast the query the answer belongs to.
|
||||
pub async fn fetch_once(url: &str) -> Result<Option<Fetched>, FetchError> {
|
||||
fetch_with_attempts(url, 1).await
|
||||
}
|
||||
|
||||
/// Total attempts of the retried [`fetch`] (3: the initial try plus two).
|
||||
const MAX_FETCH_ATTEMPTS: u32 = 3;
|
||||
|
||||
async fn fetch_with_attempts(url: &str, attempts: u32) -> Result<Option<Fetched>, FetchError> {
|
||||
let Some(site) = find_site(url) else {
|
||||
return Ok(None);
|
||||
};
|
||||
for attempt in 0..3u32 {
|
||||
for attempt in 0..attempts.max(1) {
|
||||
match site.fetch_from_url(url).await {
|
||||
Ok(fetched) => {
|
||||
// Per-request detail: debug only, keyed by the post id.
|
||||
@@ -391,7 +405,7 @@ pub async fn fetch(url: &str) -> Result<Option<Fetched>, FetchError> {
|
||||
return Ok(Some(fetched));
|
||||
}
|
||||
Err(err) => {
|
||||
if site.is_retryable(&err) && attempt < 2 {
|
||||
if site.is_retryable(&err) && attempt + 1 < attempts {
|
||||
tokio::time::sleep(Duration::from_secs(1 << attempt)).await;
|
||||
} else {
|
||||
return Err(err);
|
||||
|
||||
Reference in New Issue
Block a user