|
@@ -1724,10 +1724,15 @@ namespace ClankerSaddle.Services {
|
|
|
stored_through = seq;
|
|
stored_through = seq;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- int64 next = body.has_member("next")
|
|
|
|
|
- && body.get_member("next").get_value_type() == typeof(int64)
|
|
|
|
|
- ? body.get_int_member("next") : stored_through + 1;
|
|
|
|
|
- int64 target = fully_consumed ? next : stored_through + 1;
|
|
|
|
|
|
|
+ // The cursor advances ONLY over chunks actually served and
|
|
|
|
|
+ // stored. The daemon's `next` is deliberately NOT trusted
|
|
|
|
|
+ // beyond that: a daemon-side snapshot race (chunks appended
|
|
|
|
|
+ // after the array was built but before `next` was computed)
|
|
|
|
|
+ // once produced responses whose `next` skipped 33 single
|
|
|
|
|
+ // chunks — trusting it here meant they were never
|
|
|
|
|
+ // re-fetched. `next` is advisory; re-fetch overlap dedupes
|
|
|
|
|
+ // by seq.
|
|
|
|
|
+ int64 target = stored_through + 1;
|
|
|
if (target > since) {
|
|
if (target > since) {
|
|
|
poll_state.store_raw_since(session_id, target);
|
|
poll_state.store_raw_since(session_id, target);
|
|
|
}
|
|
}
|