Skip to content

fix: validate --inplace/--append vs --partial-dir/--delay-updates conflicts#2566

Merged
oferchen merged 1 commit into
masterfrom
fix/option-mutual-exclusions
Mar 7, 2026
Merged

fix: validate --inplace/--append vs --partial-dir/--delay-updates conflicts#2566
oferchen merged 1 commit into
masterfrom
fix/option-mutual-exclusions

Conversation

@oferchen
Copy link
Copy Markdown
Owner

@oferchen oferchen commented Mar 7, 2026

Summary

  • Add ConfigConflict error type and validate() method on ClientConfigBuilder
  • Enforce mutual exclusions matching upstream rsync options.c:2406-2414:
    • --inplace + --partial-dir / --delay-updates
    • --append + --partial-dir / --delay-updates (append implies inplace)
  • Wire validation into CLI before build(), returning exit code 1 (RERR_SYNTAX)
  • 8 unit tests covering all conflict combinations and non-conflicting cases

Test plan

  • CI passes (fmt, clippy, nextest, Windows, macOS, musl)
  • Verify upstream rsync produces same error for rsync --inplace --partial-dir=.rsync-partial src/ dest/

@github-actions github-actions Bot added the bug Something isn't working label Mar 7, 2026
…flicts

Add mutual exclusion validation matching upstream rsync options.c:2406-2414:
- --inplace + --partial-dir -> error
- --inplace + --delay-updates -> error
- --append + --partial-dir -> error (append implies inplace in upstream)
- --append + --delay-updates -> error

Add ConfigConflict error type with Display impl producing upstream-compatible
error messages. Validation runs in CLI before build(), returning exit code 1
(RERR_SYNTAX) matching upstream behavior.
@oferchen oferchen force-pushed the fix/option-mutual-exclusions branch from 6c81e7c to 165c258 Compare March 7, 2026 09:40
@oferchen oferchen merged commit 5d0d9b5 into master Mar 7, 2026
8 checks passed
@oferchen oferchen deleted the fix/option-mutual-exclusions branch March 7, 2026 09:40
oferchen added a commit that referenced this pull request May 1, 2026
…flicts (#2566)

Add mutual exclusion validation matching upstream rsync options.c:2406-2414:
- --inplace + --partial-dir -> error
- --inplace + --delay-updates -> error
- --append + --partial-dir -> error (append implies inplace in upstream)
- --append + --delay-updates -> error

Add ConfigConflict error type with Display impl producing upstream-compatible
error messages. Validation runs in CLI before build(), returning exit code 1
(RERR_SYNTAX) matching upstream behavior.
oferchen added a commit that referenced this pull request May 5, 2026
…flicts (#2566)

Add mutual exclusion validation matching upstream rsync options.c:2406-2414:
- --inplace + --partial-dir -> error
- --inplace + --delay-updates -> error
- --append + --partial-dir -> error (append implies inplace in upstream)
- --append + --delay-updates -> error

Add ConfigConflict error type with Display impl producing upstream-compatible
error messages. Validation runs in CLI before build(), returning exit code 1
(RERR_SYNTAX) matching upstream behavior.
oferchen added a commit that referenced this pull request May 21, 2026
…euristic (PIP-3 + PIP-5) (#4666)

* perf(transfer): enable parallel receive-delta by default via Path B heuristic

Wires the receiver-side parallel delta apply path into production per
`docs/design/parallel-receive-delta-default-on.md` Path B, combining
steps 4 and 5 in a single change.

- Add `PARALLEL_RECEIVE_FILE_COUNT_THRESHOLD = 100` and
  `PARALLEL_RECEIVE_BYTES_THRESHOLD = 64 MiB` on the receiver. Thresholds
  match the existing rayon parallel-stat cutoff convention and the
  `copy_file_range` 64 MiB crossover.
- Add `ReceiverContext::select_receiver_strategy(file_count, total_size)`
  (pure heuristic), `total_source_bytes()` (sums the in-memory file
  list), and `dispatch_receiver_strategy()` (logs the decision under the
  `GENR` debug channel and swaps the delta pipeline when the
  `parallel-receive-delta` feature is on).
- Call `dispatch_receiver_strategy` at the top of `run_sync`,
  `run_pipelined`, and `run_pipelined_incremental`, immediately after
  `setup_transfer` returns the file count and the file list is in
  memory.
- Surface the choice as `TransferStats::receiver_strategy_chosen` via
  the new `ReceiverStrategy { Sequential, Parallel }` enum
  (`Sequential` by default).
- Promote `parallel-receive-delta` into the `default = [...]` set on
  `engine`, `transfer`, `core`, `cli`, and the workspace binary so the
  shipped `oc-rsync` picks up the dispatch with no opt-in flag. Stay
  compatible with `--no-default-features` builds: when the feature is
  compiled out the dispatcher logs `receiver_strategy=parallel_unavailable`
  and falls back to sequential so the telemetry counter never lies
  about the path actually taken.

Tests:
- Unit coverage for the heuristic boundary matrix (below/above each
  threshold, exact-boundary, empty transfer).
- File-list-integration coverage for `total_source_bytes` and the full
  `dispatch_receiver_strategy` flow with populated file lists.

Wire-format parity stays guarded by the existing proptests (#4300 +
#4319). The soak + bench gates (criteria 1, 3, 4, 5 in section 5) are
explicit risk acceptance; PIP-4 (interop suite re-run) and PIP-6 (bench
backfill) remain as follow-ups.

Refs #1368, #2566, #2568.

* style(transfer): apply rustfmt to PIP-3+5 receiver-strategy code

CI fmt+clippy diff: collapsed select_receiver_strategy multi-line
signature and the FileEntry::new_file argument list in
dispatch_large_bytes_picks_parallel onto single lines.

Behaviour-neutral.

* fix(transfer): drop identity-op multiplier in receiver-strategy tests

clippy::identity-op fired on `1 * 1024 * 1024`. Collapsed to
`1024 * 1024` in the two boundary-matrix tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant