| ... | @@ -284,7 +284,7 @@ impl Background { | ... | @@ -284,7 +284,7 @@ impl Background { |
| 284 | news |= match outcome { | 284 | news |= match outcome { |
| 285 | Ok((stamp, moved)) => { | 285 | Ok((stamp, moved)) => { |
| 286 | watch.stamp = Some(stamp); | 286 | watch.stamp = Some(stamp); |
| 287 | watch.due = now + interval; | 287 | watch.due = watch.due.min(now + interval); |
| 288 | if moved { | 288 | if moved { |
| 289 | changed.push(path); | 289 | changed.push(path); |
| 290 | } | 290 | } |
| ... | @@ -299,7 +299,7 @@ impl Background { | ... | @@ -299,7 +299,7 @@ impl Background { |
| 299 | moved || before != summary(&watch.status) | 299 | moved || before != summary(&watch.status) |
| 300 | } | 300 | } |
| 301 | Err(error) => { | 301 | Err(error) => { |
| 302 | watch.due = now + RETRY; | 302 | watch.due = watch.due.min(now + RETRY); |
| 303 | watch.fail(&error, queued) | 303 | watch.fail(&error, queued) |
| 304 | } | 304 | } |
| 305 | }; | 305 | }; |
| ... | @@ -846,6 +846,8 @@ impl Watched { | ... | @@ -846,6 +846,8 @@ impl Watched { |
| 846 | watch.due = now + interval; | 846 | watch.due = now + interval; |
| 847 | continue; | 847 | continue; |
| 848 | } | 848 | } |
| | 849 | // Anything asking for the section during the check can only bring this forward. |
| | 850 | watch.due = now + interval.max(RETRY); |
| 849 | return Next::Check { | 851 | return Next::Check { |
| 850 | path: watch.path.clone(), | 852 | path: watch.path.clone(), |
| 851 | replica: watch.replica.clone(), | 853 | replica: watch.replica.clone(), |
| ... | @@ -1200,7 +1202,7 @@ mod tests { | ... | @@ -1200,7 +1202,7 @@ mod tests { |
| 1200 | .find(|watch| watch.path == path) | 1202 | .find(|watch| watch.path == path) |
| 1201 | .unwrap(); | 1203 | .unwrap(); |
| 1202 | watch.current = false; | 1204 | watch.current = false; |
| 1203 | watch.due = now + interval; | 1205 | watch.due = watch.due.min(now + interval); |
| 1204 | checks.push((now, path, !current)); | 1206 | checks.push((now, path, !current)); |
| 1205 | } | 1207 | } |
| 1206 | } | 1208 | } |
| ... | @@ -1468,6 +1470,45 @@ mod tests { | ... | @@ -1468,6 +1470,45 @@ mod tests { |
| 1468 | drop(rewatch); | 1470 | drop(rewatch); |
| 1469 | } | 1471 | } |
| 1470 | | 1472 | |
| | 1473 | #[test] |
| | 1474 | fn a_section_released_during_its_check_is_checked_again_at_once() { |
| | 1475 | let (sender, stamps) = mpsc::channel(); |
| | 1476 | let files = Files { |
| | 1477 | images: Arc::default(), |
| | 1478 | stamps: sender, |
| | 1479 | }; |
| | 1480 | let section = path(0); |
| | 1481 | files.write( |
| | 1482 | &section, |
| | 1483 | onestore::create_section("s.one", &section, "Author").unwrap(), |
| | 1484 | ); |
| | 1485 | let (armed, watches) = mpsc::channel(); |
| | 1486 | let remote = files.clone(); |
| | 1487 | let background = Background::start( |
| | 1488 | false, |
| | 1489 | move |reports| { |
| | 1490 | armed.send(reports).unwrap(); |
| | 1491 | let (files, listed) = (remote.clone(), remote.clone()); |
| | 1492 | let bind = move |path: &str| File(files.clone(), path.to_owned()); |
| | 1493 | let list = move |folder: String| std::future::ready(Ok(listed.list(&folder))); |
| | 1494 | Ok(((bind, list), true)) |
| | 1495 | }, |
| | 1496 | || {}, |
| | 1497 | ) |
| | 1498 | .unwrap(); |
| | 1499 | background.watch(vec![files.known(&section)]); |
| | 1500 | let watch = watches.recv().unwrap(); |
| | 1501 | assert!(quiet(&stamps, SETTLE).is_empty()); |
| | 1502 | // Holding the files parks the check reported next inside its stamp read. |
| | 1503 | let parked = files.images.lock().unwrap(); |
| | 1504 | watch.touched(std::slice::from_ref(&section)); |
| | 1505 | assert_eq!(stamps.recv_timeout(SETTLE * 2).unwrap(), section); |
| | 1506 | background.0.released(&section); |
| | 1507 | drop(parked); |
| | 1508 | assert_eq!(stamps.recv_timeout(SETTLE).unwrap(), section); |
| | 1509 | drop(background); |
| | 1510 | } |
| | 1511 | |
| 1471 | #[test] | 1512 | #[test] |
| 1472 | fn held_status_tracks_its_worker_without_retaining_the_replica() { | 1513 | fn held_status_tracks_its_worker_without_retaining_the_replica() { |
| 1473 | use crate::session::SyncState; | 1514 | use crate::session::SyncState; |