fix(serve): report a queued upload even when it is served between two polls
`serve` samples `uploads()` every 500ms and emits what changed, so an upload state shorter than that window never reached the log. Nothing surfaced this while every upload sat on its slot for a 500ms linger, which was exactly one poll; with the linger gone a peer can queue and be served between two samples, and "it had to wait" — the one thing the queue exists to record — silently disappeared. The pump now keeps whatever it left waiting, and `serve` drains that alongside the snapshot, so the fact survives regardless of when the next sample lands. The list is deduplicated per peer and file and capped, so a caller that never drains cannot grow it without bound. This is what made cli_e2e::serve_reports_a_queued_upload_once_the_slots_are_full fail on CI while passing locally: the assertion was real, and it was timing that decided whether the client could answer it.
This commit is contained in:
@@ -138,6 +138,18 @@ pub fn serve(
|
||||
let deadline = span.map(|span| Instant::now() + span);
|
||||
let mut reported: HashMap<(String, String), UploadRecord> = HashMap::new();
|
||||
while deadline.is_none_or(|deadline| Instant::now() < deadline) {
|
||||
// Queued states first, and from the client's own record rather than
|
||||
// this snapshot: with few slots and small files a peer can queue and be
|
||||
// served well inside one poll, and "it had to wait" is precisely what a
|
||||
// transfer log exists to report.
|
||||
for queued in session.client.take_upload_events() {
|
||||
let record = upload_record(&queued);
|
||||
let key = (record.user.clone(), record.path.clone());
|
||||
if reported.get(&key) != Some(&record) {
|
||||
ctx.out.emit(&record);
|
||||
reported.insert(key, record);
|
||||
}
|
||||
}
|
||||
for upload in session.client.uploads() {
|
||||
let record = upload_record(&upload);
|
||||
let key = (record.user.clone(), record.path.clone());
|
||||
|
||||
Reference in New Issue
Block a user