1
0
mirror of https://github.com/SKCraft/Launcher.git synced 2024-11-30 13:13:58 +01:00

Added better handling of failed downloads.

This commit is contained in:
sk89q 2014-01-09 09:04:22 -08:00
parent 51907d99b3
commit 8f922b4edb
2 changed files with 24 additions and 11 deletions

View File

@ -34,6 +34,7 @@ import static com.skcraft.launcher.util.SharedLocale._;
@Log @Log
public class HttpDownloader implements Downloader { public class HttpDownloader implements Downloader {
private final Random random = new Random();
private final HashFunction hf = Hashing.sha1(); private final HashFunction hf = Hashing.sha1();
private final File tempDir; private final File tempDir;
@ -45,10 +46,10 @@ public class HttpDownloader implements Downloader {
private final Set<String> usedKeys = new HashSet<String>(); private final Set<String> usedKeys = new HashSet<String>();
private final List<HttpDownloadJob> running = new ArrayList<HttpDownloadJob>(); private final List<HttpDownloadJob> running = new ArrayList<HttpDownloadJob>();
private final List<HttpDownloadJob> failed = new ArrayList<HttpDownloadJob>();
private long downloaded = 0; private long downloaded = 0;
private long total = 0; private long total = 0;
private int left = 0; private int left = 0;
private boolean hasError = false;
/** /**
* Create a new downloader using the given executor. * Create a new downloader using the given executor.
@ -132,8 +133,10 @@ public class HttpDownloader implements Downloader {
throw new IOException("Something went wrong", e); throw new IOException("Something went wrong", e);
} }
if (hasError) { synchronized (this) {
throw new IOException("Some files could not be downloaded"); if (failed.size() > 0) {
throw new IOException(failed.size() + "files could not be downloaded");
}
} }
} finally { } finally {
executor.shutdownNow(); executor.shutdownNow();
@ -155,15 +158,20 @@ public class HttpDownloader implements Downloader {
@Override @Override
public synchronized String getStatus() { public synchronized String getStatus() {
String failMessage = _("downloader.failedCount", failed.size());
if (running.size() == 1) { if (running.size() == 1) {
return _("downloader.downloadingItem", running.get(0).getName()) + "\n" + running.get(0).getStatus(); return _("downloader.downloadingItem", running.get(0).getName()) +
"\n" + running.get(0).getStatus() +
"\n" + failMessage;
} else if (running.size() > 0) { } else if (running.size() > 0) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for (HttpDownloadJob job : running) { for (HttpDownloadJob job : running) {
builder.append("\n"); builder.append("\n");
builder.append(job.getStatus()); builder.append(job.getStatus());
} }
return _("downloader.downloadingList", queue.size(), left) + builder.toString(); return _("downloader.downloadingList", queue.size(), left, failed.size()) +
builder.toString() +
"\n" + failMessage;
} else { } else {
return _("downloader.noDownloads"); return _("downloader.noDownloads");
} }
@ -191,13 +199,19 @@ public class HttpDownloader implements Downloader {
} }
download(); download();
synchronized (HttpDownloader.this) {
downloaded += size;
}
} catch (IOException e) { } catch (IOException e) {
hasError = true; synchronized (HttpDownloader.this) {
failed.add(this);
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
log.info("Download of " + destFile + " was interrupted"); log.info("Download of " + destFile + " was interrupted");
} finally { } finally {
synchronized (HttpDownloader.this) { synchronized (HttpDownloader.this) {
downloaded += size; left--;
running.remove(this); running.remove(this);
} }
} }
@ -228,14 +242,13 @@ public class HttpDownloader implements Downloader {
for (URL url : urls) { for (URL url : urls) {
// Sleep between each trial // Sleep between each trial
if (!first) { if (!first) {
Thread.sleep(retryDelay); Thread.sleep((long) (retryDelay / 2 + (random.nextDouble() * retryDelay)));
} }
first = false; first = false;
try { try {
request = HttpRequest.get(url); request = HttpRequest.get(url);
request.execute().expectResponseCode(200).saveContent(file); request.execute().expectResponseCode(200).saveContent(file);
left--;
return; return;
} catch (IOException e) { } catch (IOException e) {
lastException = e; lastException = e;

View File

@ -121,10 +121,11 @@ console.confirmKill=Are sure that you wish to close the game forcefully? You may
console.confirmKillTitle=Are you sure? console.confirmKillTitle=Are you sure?
downloader.downloadingItem=Downloading {0}... downloader.downloadingItem=Downloading {0}...
downloader.downloadingList=Downloading {0} files... ({1} remaining) downloader.downloadingList=Downloading {0} files... ({1} remaining, {2} failed)
downloader.jobProgress={1,number}%\t{0} downloader.jobProgress={1,number}%\t{0}
downloader.jobPending=...\t{0} downloader.jobPending=...\t{0}
downloader.noDownloads=No pending downloads. downloader.noDownloads=No pending downloads.
downloader.failedCount=({0} have failed)
progress.defaultStatus=Working... progress.defaultStatus=Working...
progress.percentTitle=({0}%) {1} progress.percentTitle=({0}%) {1}
@ -145,7 +146,6 @@ instanceResetter.resetting=Resetting {0}...
instanceLoader.loadingLocal=Loading local instances from disk... instanceLoader.loadingLocal=Loading local instances from disk...
instanceLoader.checkingRemote=Checking for new modpacks... instanceLoader.checkingRemote=Checking for new modpacks...
instanceLauncher.preparing=Preparing for launch... instanceLauncher.preparing=Preparing for launch...
instanceLauncher.preparingAssets=Preparing {0} assets for game...
instanceLauncher.collectingArgs=Collecting arguments... instanceLauncher.collectingArgs=Collecting arguments...
instanceLauncher.startingJava=Starting java... instanceLauncher.startingJava=Starting java...