exlab_wizard.sync.file_stability#

Pre-rclone file-stability guard: confirm files have stopped growing.

Polls st_size on a fixed interval and reports whether a file’s size has been identical across N consecutive observations. Used as a pre-flight check before rclone sync invocations so only complete files transfer.

The module is intentionally stdlib-only and free of project imports so it can be reused unchanged by external job scripts / a CLI as well as by the in-process sync worker.

Functions

is_stable(path, interval, checks, timeout)

Return True once path's size is constant across checks polls.

wait_until_stable(paths, interval, checks, ...)

Poll paths concurrently; return (stable, unstable).

exlab_wizard.sync.file_stability.is_stable(path, interval, checks, timeout)[source]#

Return True once path’s size is constant across checks polls.

Parameters:
  • path (Path) – File to observe (stat() follows symlinks).

  • interval (float) – Seconds between polls. Must be > 0.

  • checks (int) – Consecutive equal observations required. Must be >= 2.

  • timeout (float) – Wall-clock budget in seconds; exceeding it returns False.

Return type:

bool

Returns:

True if the size was identical across checks consecutive polls (an all-zero-size file counts as stable). False if the file disappears at any poll or the timeout elapses first.

Raises:

ValueError – If interval <= 0 or checks < 2.

Notes

On NFS mounts set interval >= actimeo (typically >= 30 s) so the attribute cache does not mask a still-growing file. On Windows an exclusively-locked file may report size == 0 via stat(); account for that at the call site. No busy-wait: time.sleep is used between polls. Thread-safe: no shared mutable state.

exlab_wizard.sync.file_stability.wait_until_stable(paths, interval, checks, timeout, max_workers=8)[source]#

Poll paths concurrently; return (stable, unstable).

Parameters:
  • paths (Iterable[Path]) – Files to observe.

  • interval (float) – Seconds between polls (forwarded to is_stable()).

  • checks (int) – Consecutive equal observations required.

  • timeout (float) – Per-file wall-clock budget in seconds.

  • max_workers (int) – Thread cap (one thread per file, bounded) to avoid NFS overload. Defaults to 8.

Returns:

files that reached stability, and files that did not (missing, still growing, or timed out).

Return type:

tuple[list[Path], list[Path]]

Raises:

ValueError – If interval <= 0 or checks < 2 (validated per file by is_stable()).