Skip to content

Commit 4a1fdf8

Browse files
authored
Parallelize using CompletableFuture.runAsync() (#7)
1 parent ecb82da commit 4a1fdf8

File tree

1 file changed

+61
-23
lines changed

1 file changed

+61
-23
lines changed

scripts/docBuilder.java

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,11 @@
3333
import java.util.HashMap;
3434
import java.util.List;
3535
import java.util.Map;
36-
import java.util.Scanner;
3736
import java.util.concurrent.Callable;
3837
import java.util.concurrent.CompletableFuture;
38+
import java.util.stream.Collectors;
3939

4040
import org.apache.log4j.Logger;
41-
import org.apache.commons.text.StringSubstitutor;
4241
import org.apache.log4j.BasicConfigurator;
4342

4443
import org.apache.commons.io.filefilter.WildcardFileFilter;
@@ -148,6 +147,7 @@ public GitHubFolderDownloader(String accessToken) {
148147
}
149148

150149
public void downloadFolder(String owner, String repo, String ref, String path, Path destPath) throws IOException, URISyntaxException {
150+
List<CompletableFuture<Void>> futures = new ArrayList<>();
151151

152152
// Create destination directory if it doesn't exist
153153
LOGGER.debug(
@@ -165,24 +165,33 @@ public void downloadFolder(String owner, String repo, String ref, String path, P
165165
);
166166

167167
for (GitHubContent item : contents) {
168-
String type = item.getType();
169-
String itemPath = item.getPath();
170-
String itemName = item.getName();
171-
172-
if ("file".equals(type)) {
173-
// Download file
174-
String downloadUrl = item.getDownloadUrl();
175-
if (downloadUrl == null) {
176-
// For some refs, we need to fetch the raw content differently
177-
downloadUrl = String.format("https://raw.githubusercontent.com/%s/%s/%s/%s",
178-
owner, repo, ref, itemPath);
168+
futures.add(CompletableFuture.runAsync(() -> {
169+
try {
170+
String type = item.getType();
171+
String itemPath = item.getPath();
172+
String itemName = item.getName();
173+
174+
if ("file".equals(type)) {
175+
// Download file
176+
String downloadUrl = item.getDownloadUrl();
177+
if (downloadUrl == null) {
178+
// For some refs, we need to fetch the raw content differently
179+
downloadUrl = String.format("https://raw.githubusercontent.com/%s/%s/%s/%s",
180+
owner, repo, ref, itemPath);
181+
}
182+
183+
downloadFile(downloadUrl, destPath.resolve(itemName));
184+
} else if ("dir".equals(type)) {
185+
// Recursively download subdirectory
186+
downloadFolder(owner, repo, ref, itemPath, destPath.resolve(itemName));
187+
}
188+
} catch (Exception e) {
189+
throw new RuntimeException(e);
179190
}
180-
downloadFile(downloadUrl, destPath.resolve(itemName));
181-
} else if ("dir".equals(type)) {
182-
// Recursively download subdirectory
183-
downloadFolder(owner, repo, ref, itemPath, destPath.resolve(itemName));
184-
}
191+
}));
185192
}
193+
194+
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
186195
}
187196

188197
private String makeApiRequest(String apiUrl) throws IOException, URISyntaxException {
@@ -457,6 +466,12 @@ public Integer call() throws Exception {
457466
ObjectMapper objectMapper = new ObjectMapper();
458467
List<Source> sources = objectMapper.readValue(bufferedReader, new TypeReference<List<Source>>(){});
459468

469+
Map<Source, List<CompletableFuture<Void>>> sourceFutures = sources.stream()
470+
.collect(Collectors.toMap(
471+
source -> source,
472+
source -> new ArrayList<>()
473+
));
474+
460475
this.docsRootPath = Paths.get(docsRoot);
461476
this.templateDirPath = Paths.get(templateDir);
462477

@@ -465,18 +480,41 @@ public Integer call() throws Exception {
465480
for (Source source : sources) {
466481
LOGGER.info("Found source: " + source);
467482

468-
//Download the dev branch
469-
processSource(ghFolderDownloader, source, source.getDevelopmentBranch(), false);
483+
sourceFutures.get(source).add(CompletableFuture.runAsync(() -> {
484+
try {
485+
//Download the dev branch
486+
processSource(ghFolderDownloader, source, source.getDevelopmentBranch(), false);
487+
} catch (Exception e) {
488+
throw new RuntimeException(e);
489+
}
490+
}));
470491

471492
//Download each of the tags
472493
for (String tag : source.getTags()) {
473-
processSource(ghFolderDownloader, source, tag, true);
494+
sourceFutures.get(source).add(CompletableFuture.runAsync(() -> {
495+
try {
496+
processSource(ghFolderDownloader, source, tag, true);
497+
} catch (Exception e) {
498+
throw new RuntimeException(e);
499+
}
500+
}));
474501
}
475502

476-
// Create the contents page for this source
477-
createSourceContentsPage(source);
503+
// Wait for the development branch and tags of this source to finish processing, then generate a contents page
504+
CompletableFuture<Void> branchAndTagFutures = CompletableFuture.allOf(sourceFutures.get(source).toArray(new CompletableFuture[0]));
505+
sourceFutures.get(source).add(branchAndTagFutures.thenRun(() -> {
506+
try {
507+
// Create the contents page for this source
508+
createSourceContentsPage(source);
509+
} catch (IOException e) {
510+
throw new RuntimeException(e);
511+
}
512+
}));
478513
}
479514

515+
// Wait for everything to finish processing and generating
516+
CompletableFuture.allOf(sourceFutures.values().stream().flatMap(List::stream).toArray(CompletableFuture[]::new)).join();
517+
480518
return 0;
481519
}
482520
}

0 commit comments

Comments
 (0)