diff --git a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3MinioBasicCredentialsRestIT.java b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3MinioBasicCredentialsRestIT.java index 3d7c8dd150610..a314372464ff4 100644 --- a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3MinioBasicCredentialsRestIT.java +++ b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3MinioBasicCredentialsRestIT.java @@ -21,6 +21,9 @@ import java.util.Locale; +import static org.elasticsearch.repositories.s3.S3Service.REPOSITORY_S3_CAS_ANTI_CONTENTION_DELAY_SETTING; +import static org.elasticsearch.repositories.s3.S3Service.REPOSITORY_S3_CAS_TTL_SETTING; + @ThreadLeakFilters(filters = { TestContainersThreadFilter.class }) @ThreadLeakScope(ThreadLeakScope.Scope.NONE) // https://github.com/elastic/elasticsearch/issues/102482 public class RepositoryS3MinioBasicCredentialsRestIT extends AbstractRepositoryS3RestTestCase { @@ -39,6 +42,10 @@ public class RepositoryS3MinioBasicCredentialsRestIT extends AbstractRepositoryS .keystore("s3.client." + CLIENT + ".access_key", ACCESS_KEY) .keystore("s3.client." + CLIENT + ".secret_key", SECRET_KEY) .setting("s3.client." + CLIENT + ".endpoint", minioFixture::getAddress) + // Skip listing of pre-existing uploads during a CAS because MinIO sometimes leaks them; also reduce the delay before proceeding + // TODO do not set these if running a MinIO version in which https://github.com/minio/minio/issues/21189 is fixed + .setting(REPOSITORY_S3_CAS_TTL_SETTING.getKey(), "-1") + .setting(REPOSITORY_S3_CAS_ANTI_CONTENTION_DELAY_SETTING.getKey(), "100ms") .build(); @ClassRule diff --git a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java index b7d32920927aa..6f9ac01929eca 100644 --- a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java +++ b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java @@ -842,6 +842,11 @@ void run(BytesReference expected, BytesReference updated, ActionListener upload.getInitiated().after(expiryDate))) { logger.trace("[{}] fresh preexisting uploads vs {}", blobKey, expiryDate); return true; @@ -929,7 +930,7 @@ private int getUploadIndex(String targetUploadId, List multipar final var currentTimeMillis = blobStore.getThreadPool().absoluteTimeInMillis(); final var ageMillis = currentTimeMillis - multipartUpload.getInitiated().toInstant().toEpochMilli(); final var expectedAgeRangeMillis = blobStore.getCompareAndExchangeTimeToLive().millis(); - if (ageMillis < -expectedAgeRangeMillis || ageMillis > expectedAgeRangeMillis) { + if (0 <= expectedAgeRangeMillis && (ageMillis < -expectedAgeRangeMillis || ageMillis > expectedAgeRangeMillis)) { logger.warn( """ compare-and-exchange of blob [{}:{}] was initiated at [{}={}] \