Skip to content

Commit f3ac497

Browse files
authored
Fix S3 delete throwing DirectoryNotEmptyException due to eventual consistency (#6833)
Signed-off-by: Paolo Di Tommaso <paolo.ditommaso@gmail.com>
1 parent f30d782 commit f3ac497

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

plugins/nf-amazon/src/main/nextflow/cloud/aws/nio/S3FileSystemProvider.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -485,13 +485,11 @@ public void delete(Path path) throws IOException {
485485
throw new NoSuchFileException("the path: " + FilesEx.toUriString(s3Path) + " does not exist");
486486
}
487487

488-
if (Files.isDirectory(path)){
489-
try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)){
490-
if (stream.iterator().hasNext()){
491-
throw new DirectoryNotEmptyException("the path: " + FilesEx.toUriString(s3Path) + " is a directory and is not empty");
492-
}
493-
}
494-
}
488+
// NOTE: S3 directories are virtual (marker objects or implied key prefixes),
489+
// so we do not check for emptiness before deleting. Enforcing POSIX-like
490+
// DirectoryNotEmptyException semantics on S3 is unreliable due to eventual
491+
// consistency and unnecessary because deleting a directory marker does not
492+
// affect its children.
495493

496494
// we delete the two objects (sometimes exists the key '/' and sometimes not)
497495
s3Path.getFileSystem().getClient()

plugins/nf-amazon/src/test/nextflow/cloud/aws/nio/AwsS3NioTest.groovy

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,24 @@ class AwsS3NioTest extends Specification implements AwsS3BaseSpec {
495495

496496
}
497497

498+
def 'should delete a non-empty directory on S3 without throwing' () {
499+
given:
500+
def bucketName = createBucket()
501+
and:
502+
createObject("$bucketName/dir1/file1.txt", 'HELLO')
503+
createObject("$bucketName/dir1/file2.txt", 'WORLD')
504+
505+
when:
506+
def path = s3path("s3://$bucketName/dir1")
507+
Files.delete(path)
508+
509+
then:
510+
noExceptionThrown()
511+
512+
cleanup:
513+
deleteBucket(bucketName)
514+
}
515+
498516
@Ignore //FIXME
499517
def 'should validate exists method' () {
500518
given:

0 commit comments

Comments
 (0)