s3: further improve filer consistency retry logic for CI environment
- Increase retry attempts from 5 to 8 for both updateLatestVersionInDirectory
and getLatestObjectVersion functions
- Increase base delay from 50ms to 100ms with exponential backoff up to 6.4s
- Add specific retry logic for 'no Extended metadata' race condition where
.versions directory exists but metadata is not yet written
- Add detailed timing logs to track retry delays and total wait times
- Addresses persistent CI failures where even 5 retries with 400ms max delay
were insufficient for filer store consistency in GitHub Actions environment
glog.V(0).Infof("CI-DEBUG: updateLatestVersionInDirectory: attempt %d/%d failed to get .versions entry for %s/%s: %v",attempt,maxRetries,bucket,object,err)
glog.V(0).Infof("CI-DEBUG: updateLatestVersionInDirectory: attempt %d/%d failed to get .versions entry for %s/%s: %v",attempt,maxRetries,bucket,object,err)
glog.V(0).Infof("CI-DEBUG: updateLatestVersionInDirectory: sleeping %v before retry %d",delay,attempt+1)
time.Sleep(delay)
time.Sleep(delay)
}
}
}
}
iferr!=nil{
iferr!=nil{
glog.Errorf("updateLatestVersionInDirectory: failed to get .versions directory for %s/%s after %d attempts: %v",bucket,object,maxRetries,err)
glog.Errorf("updateLatestVersionInDirectory: failed to get .versions directory for %s/%s after %d attempts: %v",bucket,object,maxRetries,err)
glog.V(0).Infof("CI-DEBUG: updateLatestVersionInDirectory: FAILED to get .versions entry for %s/%s after %d attempts: %v",bucket,object,maxRetries,err)
glog.V(0).Infof("CI-DEBUG: updateLatestVersionInDirectory: FAILED to get .versions entry for %s/%s after %d attempts (total delay ~%dms): %v",bucket,object,maxRetries,(100*(1<<maxRetries-1)-100),err)
returnfmt.Errorf("failed to get .versions directory after %d attempts: %w",maxRetries,err)
returnfmt.Errorf("failed to get .versions directory after %d attempts: %w",maxRetries,err)
glog.V(0).Infof("CI-DEBUG: getLatestObjectVersion: attempt %d/%d failed to get .versions directory for %s/%s: %v",attempt,maxRetries,bucket,object,err)
glog.V(0).Infof("CI-DEBUG: getLatestObjectVersion: attempt %d/%d failed to get .versions directory for %s/%s: %v",attempt,maxRetries,bucket,object,err)
// before versioning was enabled on the bucket. Fall back to checking for a
// before versioning was enabled on the bucket. Fall back to checking for a
// regular (non-versioned) object file.
// regular (non-versioned) object file.
glog.V(1).Infof("getLatestObjectVersion: no .versions directory for %s%s after %d attempts (error: %v), checking for pre-versioning object",bucket,object,maxRetries,err)
glog.V(1).Infof("getLatestObjectVersion: no .versions directory for %s%s after %d attempts (error: %v), checking for pre-versioning object",bucket,object,maxRetries,err)
glog.V(0).Infof("CI-DEBUG: getLatestObjectVersion: no .versions directory for %s/%s after %d attempts (error: %v), falling back to pre-versioning",bucket,object,maxRetries,err)
glog.V(0).Infof("CI-DEBUG: getLatestObjectVersion: no .versions directory for %s/%s after %d attempts (total delay ~%dms, error: %v), falling back to pre-versioning",bucket,object,maxRetries,(100*(1<<maxRetries-1)-100),err)
// Check if directory has latest version metadata - retry if missing due to race condition
ifversionsEntry.Extended==nil{
ifversionsEntry.Extended==nil{
// No metadata means all versioned objects have been deleted.
// Fall back to checking for a pre-versioning object.
glog.V(2).Infof("getLatestObjectVersion: no Extended metadata in .versions directory for %s%s, checking for pre-versioning object",bucket,object)
glog.V(0).Infof("CI-DEBUG: getLatestObjectVersion: .versions directory exists but NO Extended metadata for %s/%s - possible race condition",bucket,object)
glog.V(0).Infof("CI-DEBUG: getLatestObjectVersion: .versions directory exists but NO Extended metadata for %s/%s - retrying to handle race condition",bucket,object)
// Retry a few times to handle the race condition where directory exists but metadata is not yet written
returnnil,fmt.Errorf("no version metadata in .versions directory and no regular object found for %s%s",bucket,object)
ifversionsEntry.Extended!=nil{
glog.V(0).Infof("CI-DEBUG: getLatestObjectVersion: metadata retry %d SUCCESS - found Extended metadata for %s/%s",metaAttempt,bucket,object)
break
}
}
}
glog.V(2).Infof("getLatestObjectVersion: found pre-versioning object for %s%s (no Extended metadata case)",bucket,object)
returnregularEntry,nil
// If still no metadata after retries, fall back to pre-versioning object
ifversionsEntry.Extended==nil{
glog.V(2).Infof("getLatestObjectVersion: no Extended metadata in .versions directory for %s%s after retries, checking for pre-versioning object",bucket,object)
glog.V(0).Infof("CI-DEBUG: getLatestObjectVersion: NO Extended metadata for %s/%s after %d retries - falling back to pre-versioning",bucket,object,metadataRetries)