Settle the images whose best preview is under the floor
The floor introduces a state the sweep had no arm for. An image whose largest embedded preview is genuinely smaller than 1025px now comes back from index_preview as an error, lands in the generic Err arm, and is counted as failed -- which means no face_index row, which means it is still outstanding, which means the next sweep fetches exactly the same bytes and refuses them again. For ever, on every run, at one range request each. The previous behaviour was wrong but at least terminated; this would not. So ProxyTooSmall gets its own arm, and it records a marker at the true edge rather than nothing. That is the difference between "we looked and found nothing" -- which would be a lie, since nothing was looked at -- and "this was examined at 900px, which is the best this file has". The first is unrecoverable; the second is a fact source_edge was added to carry, and a later floor or a bigger proxy can select on it deliberately the way V12 just did. Counted separately from failures all the way up, because they are not failures and reading them as such would misdescribe a library of small scans as a broken network. The summary line says how many and why. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+37
-3
@@ -3249,6 +3249,7 @@ pub fn spawn_face_sweep(
|
||||
let models = std::cell::RefCell::new((&mut detector, &mut embedder));
|
||||
|
||||
let (mut done, mut images, mut found, mut failed) = (0usize, 0usize, 0usize, 0usize);
|
||||
let mut too_small = 0usize;
|
||||
let mut offline = false;
|
||||
|
||||
// TRACES: FR-NC-6c
|
||||
@@ -3273,6 +3274,7 @@ pub fn spawn_face_sweep(
|
||||
let mut discard = Vec::new();
|
||||
let mut attempted = 0usize;
|
||||
let mut failed = 0usize;
|
||||
let mut too_small = 0usize;
|
||||
let mut offline = false;
|
||||
for req in lane {
|
||||
attempted += 1;
|
||||
@@ -3332,6 +3334,29 @@ pub fn spawn_face_sweep(
|
||||
};
|
||||
indexed.push((req.image_id, faces, edge, keep));
|
||||
}
|
||||
// Not a failure, and it must not
|
||||
// be retried as one. The largest
|
||||
// preview this file has is below the
|
||||
// detector's floor, so the next sweep
|
||||
// would fetch the same bytes and
|
||||
// refuse them again, for ever. A
|
||||
// marker at the true edge settles it:
|
||||
// the image leaves the work list, and
|
||||
// `source_edge` records what it was
|
||||
// examined at, so a later floor or a
|
||||
// bigger proxy can come back for it on
|
||||
// purpose rather than by accident.
|
||||
Err(dr_face::FaceError::ProxyTooSmall {
|
||||
edge, ..
|
||||
}) => {
|
||||
too_small += 1;
|
||||
indexed.push((
|
||||
req.image_id,
|
||||
Vec::new(),
|
||||
edge,
|
||||
None,
|
||||
));
|
||||
}
|
||||
Err(e) => {
|
||||
log::debug!("face sweep: {}: {e}", req.path);
|
||||
failed += 1;
|
||||
@@ -3350,14 +3375,15 @@ pub fn spawn_face_sweep(
|
||||
}
|
||||
}
|
||||
}
|
||||
(indexed, attempted, failed, offline)
|
||||
(indexed, attempted, failed, too_small, offline)
|
||||
}
|
||||
}))
|
||||
.await;
|
||||
|
||||
for (indexed, attempted, lane_failed, lane_offline) in results {
|
||||
for (indexed, attempted, lane_failed, lane_too_small, lane_offline) in results {
|
||||
done += attempted;
|
||||
failed += lane_failed;
|
||||
too_small += lane_too_small;
|
||||
offline |= lane_offline;
|
||||
for (image_id, faces, edge, keep) in indexed {
|
||||
// Before the detections, so a kill between the two
|
||||
@@ -3430,7 +3456,15 @@ pub fn spawn_face_sweep(
|
||||
}
|
||||
|
||||
log::info!(
|
||||
"face sweep: {found} face(s) across {images} image(s), {failed} failed{}",
|
||||
"face sweep: {found} face(s) across {images} image(s), {failed} failed{}{}",
|
||||
if too_small > 0 {
|
||||
format!(
|
||||
", {too_small} whose best preview is under the {}px floor",
|
||||
dr_face::MIN_DETECT_EDGE
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
if offline { ", server went away" } else { "" }
|
||||
);
|
||||
let _ = tx.send(FaceSweepMessage::Finished {
|
||||
|
||||
Reference in New Issue
Block a user