diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MultipleSourceVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MultipleSourceVersionList.java index 4a77cc5136..4f2676c502 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MultipleSourceVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MultipleSourceVersionList.java @@ -20,6 +20,8 @@ import org.jackhuang.hmcl.task.Task; import java.util.Arrays; +import java.util.Collection; +import java.util.List; import static org.jackhuang.hmcl.util.logging.Logger.LOG; @@ -47,25 +49,58 @@ public Task refreshAsync() { private Task refreshAsync(String gameVersion, int sourceIndex) { VersionList versionList = backends[sourceIndex]; - return versionList.refreshAsync(gameVersion) - .thenComposeAsync(() -> { + Task refreshTask = versionList.refreshAsync(gameVersion); + + return new Task() { + private Task nextTask = null; + + { + setSignificance(TaskSignificance.MODERATE); + setName("MultipleSourceVersionList.refreshAsync(" + sourceIndex + ")"); + } + + @Override + public Collection> getDependents() { + return List.of(refreshTask); + } + + @Override + public Collection> getDependencies() { + return nextTask != null ? List.of(nextTask) : List.of(); + } + + @Override + public boolean isRelyingOnDependents() { + return false; + } + + @Override + public void execute() throws Exception { + if (isDependentsSucceeded()) { lock.writeLock().lock(); try { versions.putAll(gameVersion, versionList.getVersions(gameVersion)); - } catch (Exception e) { - if (sourceIndex == backends.length - 1) { - LOG.warning("Failed to fetch versions list from all sources", e); - throw e; - } else { - LOG.warning("Failed to fetch versions list and try to fetch from other source", e); - return refreshAsync(gameVersion, sourceIndex + 1); - } } finally { lock.writeLock().unlock(); } - return null; - }); + setResult(refreshTask.getResult()); + } else { + Exception exception = refreshTask.getException(); + assert exception != null; + + if (sourceIndex == backends.length - 1) { + LOG.warning("Failed to fetch versions list from all sources", exception); + setSignificance(TaskSignificance.MINOR); + throw exception; + } else { + LOG.warning("Failed to fetch versions list and try to fetch from other source", exception); + nextTask = refreshAsync(gameVersion, sourceIndex + 1); + nextTask.storeTo(this::setResult); + } + } + } + }; } @Override