update balanced download provider
This commit is contained in:
parent
8d19196a35
commit
8508e52241
|
@ -84,7 +84,7 @@ public final class DownloadProviders {
|
|||
|
||||
AdaptedDownloadProvider fileProvider = new AdaptedDownloadProvider();
|
||||
fileProvider.setDownloadProviderCandidates(Arrays.asList(MCBBS, BMCLAPI, MOJANG));
|
||||
BalancedDownloadProvider balanced = new BalancedDownloadProvider(Arrays.asList(MCBBS, BMCLAPI, MOJANG));
|
||||
BalancedDownloadProvider balanced = new BalancedDownloadProvider(MOJANG, MCBBS, BMCLAPI);
|
||||
|
||||
providersById = mapOf(
|
||||
pair("official", new AutoDownloadProvider(MOJANG, fileProvider)),
|
||||
|
|
|
@ -18,20 +18,17 @@
|
|||
package com.tungsten.fclcore.download;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Official Download Provider fetches version list from Mojang and
|
||||
* download files from mcbbs.
|
||||
*/
|
||||
public class BalancedDownloadProvider implements DownloadProvider {
|
||||
List<DownloadProvider> candidates;
|
||||
public final class BalancedDownloadProvider implements DownloadProvider {
|
||||
private final DownloadProvider[] candidates;
|
||||
private final Map<String, VersionList<?>> versionLists = new HashMap<>();
|
||||
|
||||
Map<String, VersionList<?>> versionLists = new HashMap<>();
|
||||
|
||||
public BalancedDownloadProvider(List<DownloadProvider> candidates) {
|
||||
public BalancedDownloadProvider(DownloadProvider... candidates) {
|
||||
this.candidates = candidates;
|
||||
}
|
||||
|
||||
|
@ -52,13 +49,13 @@ public class BalancedDownloadProvider implements DownloadProvider {
|
|||
|
||||
@Override
|
||||
public VersionList<?> getVersionListById(String id) {
|
||||
if (!versionLists.containsKey(id)) {
|
||||
versionLists.put(id, new MultipleSourceVersionList(
|
||||
candidates.stream()
|
||||
.map(downloadProvider -> downloadProvider.getVersionListById(id))
|
||||
.collect(Collectors.toList())));
|
||||
}
|
||||
return versionLists.get(id);
|
||||
return versionLists.computeIfAbsent(id, value -> {
|
||||
VersionList<?>[] lists = new VersionList<?>[candidates.length];
|
||||
for (int i = 0; i < candidates.length; i++) {
|
||||
lists[i] = candidates[i].getVersionListById(value);
|
||||
}
|
||||
return new MultipleSourceVersionList(lists);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,23 +17,26 @@
|
|||
*/
|
||||
package com.tungsten.fclcore.download;
|
||||
|
||||
import java.util.List;
|
||||
import static com.tungsten.fclcore.util.Logging.LOG;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class MultipleSourceVersionList extends VersionList<RemoteVersion> {
|
||||
|
||||
private final List<VersionList<?>> backends;
|
||||
private final VersionList<?>[] backends;
|
||||
|
||||
MultipleSourceVersionList(List<VersionList<?>> backends) {
|
||||
MultipleSourceVersionList(VersionList<?>[] backends) {
|
||||
this.backends = backends;
|
||||
|
||||
assert (backends.size() >= 1);
|
||||
assert (backends.length >= 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasType() {
|
||||
boolean hasType = backends.get(0).hasType();
|
||||
assert (backends.stream().allMatch(versionList -> versionList.hasType() == hasType));
|
||||
boolean hasType = backends[0].hasType();
|
||||
assert (Arrays.stream(backends).allMatch(versionList -> versionList.hasType() == hasType));
|
||||
return hasType;
|
||||
}
|
||||
|
||||
|
@ -47,11 +50,9 @@ public class MultipleSourceVersionList extends VersionList<RemoteVersion> {
|
|||
throw new UnsupportedOperationException("MultipleSourceVersionList does not support loading the entire remote version list.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync(String gameVersion) {
|
||||
versions.clear(gameVersion);
|
||||
return CompletableFuture.anyOf(backends.stream()
|
||||
.map(versionList -> versionList.refreshAsync(gameVersion)
|
||||
private CompletableFuture<?> refreshAsync(String gameVersion, int sourceIndex) {
|
||||
VersionList<?> versionList = backends[sourceIndex];
|
||||
CompletableFuture<Void> future = versionList.refreshAsync(gameVersion)
|
||||
.thenRunAsync(() -> {
|
||||
lock.writeLock().lock();
|
||||
|
||||
|
@ -60,7 +61,25 @@ public class MultipleSourceVersionList extends VersionList<RemoteVersion> {
|
|||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}))
|
||||
.toArray(CompletableFuture[]::new));
|
||||
});
|
||||
|
||||
if (sourceIndex == backends.length - 1) {
|
||||
return future;
|
||||
} else {
|
||||
return future.<CompletableFuture<?>>handle((ignore, e) -> {
|
||||
if (e == null) {
|
||||
return future;
|
||||
}
|
||||
|
||||
LOG.log(Level.WARNING, "Failed to fetch versions list and try to fetch from other source", e);
|
||||
return refreshAsync(gameVersion, sourceIndex + 1);
|
||||
}).thenCompose(it -> it);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync(String gameVersion) {
|
||||
versions.clear(gameVersion);
|
||||
return refreshAsync(gameVersion, 0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue