MapWithAIDataUtils: Download inside a safe ForkJoinPool

Signed-off-by: Taylor Smock <tsmock@fb.com>
pull/1/head
Taylor Smock 2022-05-31 16:12:22 -06:00
rodzic b350286a36
commit 844e67d5a1
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 625F6A74A3E4311A
1 zmienionych plików z 49 dodań i 26 usunięć

Wyświetl plik

@ -17,6 +17,7 @@ import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -147,10 +148,18 @@ public final class MapWithAIDataUtils {
final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(); final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor();
monitor.beginTask(tr("Downloading {0} Data", MapWithAIPlugin.NAME), realBounds.size()); monitor.beginTask(tr("Downloading {0} Data", MapWithAIPlugin.NAME), realBounds.size());
try { try {
realBounds.parallelStream() List<MapWithAIInfo> urls = new ArrayList<>(MapWithAIPreferenceHelper.getMapWithAIUrl());
.forEach(bound -> new ArrayList<>(MapWithAIPreferenceHelper.getMapWithAIUrl()) final List<ForkJoinTask<DataSet>> downloadedDataSets = new ArrayList<>();
.parallelStream().filter(i -> i.getUrl() != null && !i.getUrl().trim().isEmpty()) for (final Bounds bound : realBounds) {
.forEach(i -> download(monitor, dataSet, bound, i, maximumDimensions))); for (MapWithAIInfo url : urls) {
if (url.getUrl() != null && !Utils.isBlank(url.getUrl())) {
ForkJoinTask<DataSet> ds = download(monitor, bound, url, maximumDimensions);
downloadedDataSets.add(ds);
MapWithAIDataUtils.getForkJoinPool().execute(ds);
}
}
}
mergeDataSets(dataSet, downloadedDataSets);
} finally { } finally {
monitor.finishTask(); monitor.finishTask();
monitor.close(); monitor.close();
@ -179,34 +188,48 @@ public final class MapWithAIDataUtils {
* Download an area * Download an area
* *
* @param monitor The monitor to update * @param monitor The monitor to update
* @param dataSet The dataset to add to
* @param bound The bounds that are being downloading * @param bound The bounds that are being downloading
* @param mapWithAIInfo The source of the data * @param mapWithAIInfo The source of the data
* @param maximumDimensions The maximum dimensions to download * @param maximumDimensions The maximum dimensions to download
* @return A future that will have downloaded the data
*/ */
private static void download(PleaseWaitProgressMonitor monitor, DataSet dataSet, Bounds bound, private static ForkJoinTask<DataSet> download(PleaseWaitProgressMonitor monitor, Bounds bound,
MapWithAIInfo mapWithAIInfo, int maximumDimensions) { MapWithAIInfo mapWithAIInfo, int maximumDimensions) {
BoundingBoxMapWithAIDownloader downloader = new BoundingBoxMapWithAIDownloader(bound, mapWithAIInfo, return ForkJoinTask.adapt(() -> {
DetectTaskingManagerUtils.hasTaskingManagerLayer()); BoundingBoxMapWithAIDownloader downloader = new BoundingBoxMapWithAIDownloader(bound, mapWithAIInfo,
try { DetectTaskingManagerUtils.hasTaskingManagerLayer());
DataSet ds = downloader.parseOsm(monitor.createSubTaskMonitor(1, false)); try {
synchronized (MapWithAIDataUtils.class) { return downloader.parseOsm(monitor.createSubTaskMonitor(1, false));
dataSet.mergeFrom(ds); } catch (OsmTransferException e) {
if (e.getCause() instanceof SocketTimeoutException && maximumDimensions > MAXIMUM_SIDE_DIMENSIONS / 10
&& maximumDimensions / 2f > 0.5) {
return getData(bound, maximumDimensions / 2);
}
throw e;
} }
} catch (OsmTransferException e) { });
if (e.getCause() instanceof SocketTimeoutException && maximumDimensions > MAXIMUM_SIDE_DIMENSIONS / 10 }
&& maximumDimensions / 2f > 0.5) {
dataSet.mergeFrom(getData(bound, maximumDimensions / 2)); /**
} else if (e.getCause() instanceof IllegalDataException) { * Merge datasets
Logging.error(e); *
Notification notification = new Notification(); * @param original The original dataset
notification.setContent(tr("MapWithAI servers may be down.")); * @param dataSetsToMerge The datasets to merge (futures)
GuiHelper.runInEDT(notification::show); */
} else { private static void mergeDataSets(final DataSet original, final List<ForkJoinTask<DataSet>> dataSetsToMerge) {
Logging.error(e); for (ForkJoinTask<DataSet> ds : dataSetsToMerge) {
Notification notification = new Notification(); try {
GuiHelper.runInEDT(() -> notification.setContent(e.getLocalizedMessage())); original.mergeFrom(ds.join());
GuiHelper.runInEDT(notification::show); } catch (RuntimeException e) {
if (e.getCause() instanceof IllegalDataException) {
Notification notification = new Notification();
notification.setContent(tr("MapWithAI servers may be down."));
GuiHelper.runInEDT(notification::show);
} else {
Notification notification = new Notification();
GuiHelper.runInEDT(() -> notification.setContent(e.getLocalizedMessage()));
GuiHelper.runInEDT(notification::show);
}
} }
} }
} }