-
Notifications
You must be signed in to change notification settings - Fork 9.2k
HADOOP-18873. ABFS: AbfsOutputStream doesnt close DataBlocks object. #6010
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
ab37783
50e7742
7770dfa
306cac2
16455f8
1f8b7d8
0a87a03
96aca09
d9da57b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,15 +20,28 @@ | |
|
|
||
| import java.io.FileNotFoundException; | ||
| import java.io.IOException; | ||
| import java.io.OutputStream; | ||
| import java.util.HashSet; | ||
| import java.util.Random; | ||
| import java.util.Set; | ||
|
|
||
| import org.junit.Test; | ||
| import org.mockito.Mockito; | ||
|
|
||
| import org.apache.hadoop.conf.Configuration; | ||
| import org.apache.hadoop.fs.FSDataOutputStream; | ||
| import org.apache.hadoop.fs.FileSystem; | ||
| import org.apache.hadoop.fs.Path; | ||
| import org.apache.hadoop.fs.azurebfs.constants.FSOperationType; | ||
| import org.apache.hadoop.fs.azurebfs.utils.TracingHeaderValidator; | ||
| import org.apache.hadoop.fs.contract.ContractTestUtils; | ||
| import org.apache.hadoop.fs.store.BlockUploadStatistics; | ||
| import org.apache.hadoop.fs.store.DataBlocks; | ||
|
|
||
| import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.DATA_BLOCKS_BUFFER; | ||
| import static org.apache.hadoop.fs.store.DataBlocks.DATA_BLOCKS_BUFFER_ARRAY; | ||
| import static org.apache.hadoop.fs.store.DataBlocks.DATA_BLOCKS_BUFFER_DISK; | ||
| import static org.apache.hadoop.fs.store.DataBlocks.DATA_BLOCKS_BYTEBUFFER; | ||
|
|
||
| /** | ||
| * Test append operations. | ||
|
|
@@ -90,4 +103,38 @@ public void testTracingForAppend() throws IOException { | |
| fs.getFileSystemId(), FSOperationType.APPEND, false, 0)); | ||
| fs.append(testPath, 10); | ||
| } | ||
|
|
||
| @Test | ||
| public void testCloseOfDataBlockOnAppendComplete() throws Exception { | ||
| Set<String> blockBufferTypes = new HashSet<>(); | ||
| blockBufferTypes.add(DATA_BLOCKS_BUFFER_DISK); | ||
| blockBufferTypes.add(DATA_BLOCKS_BYTEBUFFER); | ||
| blockBufferTypes.add(DATA_BLOCKS_BUFFER_ARRAY); | ||
| for (String blockBufferType : blockBufferTypes) { | ||
| Configuration configuration = new Configuration(getRawConfiguration()); | ||
| configuration.set(DATA_BLOCKS_BUFFER, blockBufferType); | ||
| AzureBlobFileSystem fs = Mockito.spy( | ||
| (AzureBlobFileSystem) FileSystem.newInstance(configuration)); | ||
| AzureBlobFileSystemStore store = Mockito.spy(fs.getAbfsStore()); | ||
| Mockito.doReturn(store).when(fs).getAbfsStore(); | ||
| DataBlocks.DataBlock[] dataBlock = new DataBlocks.DataBlock[1]; | ||
| Mockito.doAnswer(getBlobFactoryInvocation -> { | ||
| DataBlocks.BlockFactory factory = Mockito.spy( | ||
| (DataBlocks.BlockFactory) getBlobFactoryInvocation.callRealMethod()); | ||
| Mockito.doAnswer(factoryCreateInvocation -> { | ||
| dataBlock[0] = Mockito.spy( | ||
| (DataBlocks.DataBlock) factoryCreateInvocation.callRealMethod()); | ||
| return dataBlock[0]; | ||
| }) | ||
| .when(factory) | ||
| .create(Mockito.anyLong(), Mockito.anyInt(), Mockito.any( | ||
| BlockUploadStatistics.class)); | ||
| return factory; | ||
| }).when(store).getBlockFactory(); | ||
| OutputStream os = fs.create(new Path("/file_" + blockBufferType)); | ||
|
||
| os.write(new byte[1]); | ||
| os.close(); | ||
| Mockito.verify(dataBlock[0], Mockito.times(1)).close(); | ||
|
||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, because the line above calls BlockUploadData.close(), a lot of the cleanup should take place already; that .startUpload() call on L315 sets the blockToUpload.buffer ref to null, so that reference doesn't retain a hold on the bytebuffer.
this is why we haven't seen problems yet like OOM/disk storage...cleanup was happening.
can you review the code to make sure the sequence of L348 always does the right thing and not fail due to some attempted double delete of the file...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the comment.
can you review the code to make sure the sequence of L348 always does the right thing and not fail due to some attempted double delete of the file...:hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/DataBlocks.java
Line 266 in f6fa5bd
hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/DataBlocks.java
Line 1118 in f6fa5bd
blockBuffer:hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/DataBlocks.java
Line 732 in f6fa5bd
hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/DataBlocks.java
Line 263 in f6fa5bd
bytebuffervariable in the inputStream :hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/DataBlocks.java
Line 806 in f6fa5bd
hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/DataBlocks.java
Line 764 in f6fa5bd
hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/DataBlocks.java
Line 667 in f6fa5bd
hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/DataBlocks.java
Lines 623 to 626 in f6fa5bd
For checking that this flow works correctly on all the types of dataBuffers, have made change in the
testCloseOfDataBlockOnAppendComplete. This will also help keep check the sanity in future on any change in the databuffer code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is safe in case of file delete, as java.io.File will return false in case file is not there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add
blockToUploadin L347 alongsideblockUploadData, for consistency and also checks for null.