s3: add retry logic for filer consistency in versioned object operations
- Add retry logic to updateLatestVersionInDirectory to handle cases where
.versions directory creation succeeds but is not immediately visible
- Add retry logic to getLatestObjectVersion for the same consistency issue
- Use 3 retries with 50ms delays to handle filer store consistency timing
- Addresses CI failures where 'filer: no entry is found in filer store'
occurs after successful directory creation
- Maintains CI debug logging to track retry attempts and outcomes
glog.V(0).Infof("CI-DEBUG: updateLatestVersionInDirectory: attempt %d/%d failed to get .versions entry for %s/%s: %v",attempt,maxRetries,bucket,object,err)
ifattempt<maxRetries{
// Brief wait before retry to allow filer consistency
time.Sleep(time.Millisecond*50)
}
}
iferr!=nil{
iferr!=nil{
glog.Errorf("updateLatestVersionInDirectory: failed to get .versions directory for %s/%s: %v",bucket,object,err)
glog.V(0).Infof("CI-DEBUG: updateLatestVersionInDirectory: FAILED to get .versions entry for %s/%s: %v",bucket,object,err)
returnfmt.Errorf("failed to get .versions directory: %w",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)
returnfmt.Errorf("failed to get .versions directory after %d attempts: %w",maxRetries,err)
}
}
glog.V(0).Infof("CI-DEBUG: updateLatestVersionInDirectory: got .versions entry for %s/%s, updating metadata",bucket,object)
glog.V(0).Infof("CI-DEBUG: updateLatestVersionInDirectory: got .versions entry for %s/%s, updating metadata",bucket,object)
glog.V(0).Infof("CI-DEBUG: getLatestObjectVersion: attempt %d/%d failed to get .versions directory for %s/%s: %v",attempt,maxRetries,bucket,object,err)
ifattempt<maxRetries{
// Brief wait before retry to allow filer consistency
time.Sleep(time.Millisecond*50)
}
}
iferr!=nil{
iferr!=nil{
// .versions directory doesn't exist - this can happen for objects that existed
// .versions directory doesn't exist - this can happen for objects that existed
// 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 (error: %v), checking for pre-versioning object",bucket,object,err)
glog.V(0).Infof("CI-DEBUG: getLatestObjectVersion: no .versions directory for %s/%s (error: %v), falling back to pre-versioning",bucket,object,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)