steveloughran commented on a change in pull request #1890: HADOOP-16854 Fix to
prevent OutOfMemoryException and Make the threadpool and bytebuffer pool common
across all AbfsOutputStream instances
URL: https://github.com/apache/hadoop/pull/1890#discussion_r394371435
##########
File path:
hadoop-tools/hadoop-azure/src/test/java/org/apache/hadoop/fs/azurebfs/ITestAzureBlobFileSystemFlush.java
##########
@@ -207,6 +210,70 @@ public Void call() throws Exception {
assertEquals((long) TEST_BUFFER_SIZE * FLUSH_TIMES, fileStatus.getLen());
}
+ @Test
+ public void testWriteWithMultipleOutputStreamAtTheSameTime()
+ throws IOException, InterruptedException, ExecutionException {
+ AzureBlobFileSystem fs = getFileSystem();
+ String testFilePath = methodName.getMethodName();
+ Path[] testPaths = new Path[CONCURRENT_STREAM_OBJS_TEST_OBJ_COUNT];
+ createNStreamsAndWriteDifferentSizesConcurrently(fs, testFilePath,
+ CONCURRENT_STREAM_OBJS_TEST_OBJ_COUNT, testPaths);
+ assertSuccessfulWritesOnAllStreams(fs,
+ CONCURRENT_STREAM_OBJS_TEST_OBJ_COUNT, testPaths);
+ }
+
+ private void assertSuccessfulWritesOnAllStreams(final FileSystem fs,
+ final int numConcurrentObjects, final Path[] testPaths)
+ throws IOException {
+ for (int i = 0; i < numConcurrentObjects; i++) {
+ FileStatus fileStatus = fs.getFileStatus(testPaths[i]);
+ int numWritesMadeOnStream = i + 1;
+ long expectedLength = TEST_BUFFER_SIZE * numWritesMadeOnStream;
+ assertThat(fileStatus.getLen(), is(equalTo(expectedLength)));
+ }
+ }
+
+ private void createNStreamsAndWriteDifferentSizesConcurrently(
+ final FileSystem fs, final String testFilePath,
+ final int numConcurrentObjects, final Path[] testPaths)
+ throws ExecutionException, InterruptedException {
+ final byte[] b = new byte[TEST_BUFFER_SIZE];
+ new Random().nextBytes(b);
+ final ExecutorService es = Executors.newFixedThreadPool(40);
+ final List<Future<Void>> futureTasks = new ArrayList<>();
+ for (int i = 0; i < numConcurrentObjects; i++) {
+ Path testPath = new Path(testFilePath + i);
+ testPaths[i] = testPath;
+ int numWritesToBeDone = i + 1;
+ futureTasks.add(es.submit(() -> {
+ try (FSDataOutputStream stream = fs.create(testPath)) {
+ makeNWritesToStream(stream, numWritesToBeDone, b, es);
+ }
+ return null;
+ }));
+ }
+ for (Future<Void> futureTask : futureTasks) {
+ futureTask.get();
+ }
+ es.shutdownNow();
+ }
+
+ private void makeNWritesToStream(final FSDataOutputStream stream,
+ final int numWrites, final byte[] b, final ExecutorService es)
+ throws IOException, ExecutionException, InterruptedException {
+ final List<Future<Void>> futureTasks = new ArrayList<>();
+ for (int i = 0; i < numWrites; i++) {
+ futureTasks.add(es.submit(() -> {
+ stream.write(b);
+ return null;
+ }));
+ }
+ for (Future<Void> futureTask : futureTasks) {
Review comment:
I'm sure there is a way to block for multiple futures. See also
FutureIOSupport.awaitFuture
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]