make the forge-notify cursor bound explicit: shared fetch-limit const + assert + docs (closes #2117)
This commit is contained in:
parent
c89642872c
commit
383bb3b083
2 changed files with 28 additions and 1 deletions
|
|
@ -28,6 +28,13 @@ use tracing::{debug, info, warn};
|
|||
|
||||
const POLL_INTERVAL_SECS: u64 = 30;
|
||||
const HTTP_TIMEOUT_SECS: u64 = 10;
|
||||
/// Page size of the unread-notifications fetch. This is also the hard
|
||||
/// bound on the persisted delivery-dedupe cursor: each poll prunes the
|
||||
/// cursor to the ids in this window, so the `forge_cursor` field in
|
||||
/// `hyperhive-harness.json` can never exceed this many entries. Keep
|
||||
/// the two coupled — bumping the fetch limit grows the cursor's ceiling
|
||||
/// with it, deliberately and visibly.
|
||||
const UNREAD_FETCH_LIMIT: usize = 50;
|
||||
/// Maximum characters of a body/comment to include in the wake message.
|
||||
const BODY_TRUNCATE: usize = 500;
|
||||
/// How long to wait between token-read retries when the token file is
|
||||
|
|
@ -743,7 +750,7 @@ async fn poll_once(
|
|||
delivered: &mut HashMap<u64, String>,
|
||||
own_login: &str,
|
||||
) {
|
||||
let url = format!("{forge_url}/api/v1/notifications?all=false&limit=50");
|
||||
let url = format!("{forge_url}/api/v1/notifications?all=false&limit={UNREAD_FETCH_LIMIT}");
|
||||
let resp = match client
|
||||
.get(&url)
|
||||
.header("Authorization", format!("token {token}"))
|
||||
|
|
@ -841,12 +848,23 @@ async fn poll_once(
|
|||
// dead weight; dropping it bounds the map to the current unread size.
|
||||
// If such a thread later goes unread again it carries a fresh
|
||||
// `updated_at` and re-delivers correctly.
|
||||
//
|
||||
// This retain IS the cursor's size bound: `current_ids` comes from a
|
||||
// single `limit=UNREAD_FETCH_LIMIT` page, so the persisted cursor can
|
||||
// never exceed that many entries — it tracks the unread *window*, not
|
||||
// the all-time notification count. The assert makes the invariant
|
||||
// loud in tests/dev if a future pagination change silently breaks it.
|
||||
let current_ids: HashSet<u64> = notifications
|
||||
.iter()
|
||||
.filter_map(|n| n["id"].as_u64())
|
||||
.collect();
|
||||
let before_prune = delivered.len();
|
||||
delivered.retain(|id, _| current_ids.contains(id));
|
||||
debug_assert!(
|
||||
delivered.len() <= UNREAD_FETCH_LIMIT,
|
||||
"dedupe cursor exceeded the fetch window ({} > {UNREAD_FETCH_LIMIT})",
|
||||
delivered.len(),
|
||||
);
|
||||
if delivered.len() != before_prune {
|
||||
cursor_dirty = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue