mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
fix(replication): mark version-id fallback ETag match as Completed, not Failed (backlog#860) (#4310)
During resync against an AWS-style target that rejects RustFS UUID versionIds,
the code retries HEAD without a versionId and compares ETags. On a match it set
`replication_action = None` ("already in sync, nothing to copy") but did not
return, so control fell through to `if replication_action != ReplicationAction::All`
— a branch meant only for the unsupported metadata-only case — and stamped the
object FAILED with "metadata-only replication is not implemented". The target
already held an identical object, yet the source recorded FAILED forever, so
AWS-style targets never converged and the MRF kept re-queuing.
Handle `ReplicationAction::None` explicitly before that branch: record it as
Completed (with the resync timestamp/`replication_resynced` bookkeeping for
ExistingObject + reset_id, mirroring the HEAD-success None path) and return.
Only `ReplicationAction::Metadata` now takes the metadata-unsupported failure
branch; `All` still proceeds to the copy. This path is the only way `None`
reaches that point (the HEAD-success None case already returns earlier).
Refs backlog#799 (B11).
This commit is contained in:
@@ -2658,6 +2658,28 @@ impl ReplicateObjectInfoExt for ReplicateObjectInfo {
|
||||
rinfo.size = size;
|
||||
rinfo.replication_action = replication_action;
|
||||
|
||||
if replication_action == ReplicationAction::None {
|
||||
// The target already holds a matching object (reached here only via
|
||||
// the version-id fallback ETag match above) — there is nothing to
|
||||
// copy. Record it as synced and return, instead of falling into the
|
||||
// metadata-unsupported failure branch below, which previously left
|
||||
// AWS-style targets permanently FAILED and never converging
|
||||
// (backlog#860 / #799 B11).
|
||||
if self.op_type == ReplicationType::ExistingObject && !tgt_client.reset_id.is_empty() {
|
||||
rinfo.resync_timestamp = format!(
|
||||
"{};{}",
|
||||
OffsetDateTime::now_utc()
|
||||
.format(&Rfc3339)
|
||||
.unwrap_or_else(|_| "invalid-time".to_string()),
|
||||
tgt_client.reset_id
|
||||
);
|
||||
rinfo.replication_resynced = true;
|
||||
}
|
||||
rinfo.duration = (OffsetDateTime::now_utc() - start_time).unsigned_abs();
|
||||
return rinfo;
|
||||
}
|
||||
|
||||
// action == Metadata: metadata-only replication is not implemented.
|
||||
if replication_action != ReplicationAction::All {
|
||||
rinfo.replication_status = ReplicationStatusType::Failed;
|
||||
rinfo.error = Some(ERR_REPLICATION_METADATA_COPY_UNSUPPORTED.to_string());
|
||||
|
||||
Reference in New Issue
Block a user