From d57803fb22aadc957a037528051c06a39945b4fb Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Wed, 13 Jan 2021 11:03:56 +0100 Subject: [PATCH] Retry if download fails for any reason (#70) fixes #35 --- lib/installer.js | 21 +++++++++++++++++++-- package-lock.json | 28 ++++++++++++++++++++++++++++ package.json | 2 ++ src/installer.ts | 23 +++++++++++++++++++++-- 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/lib/installer.js b/lib/installer.js index 4517d60..085dfac 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -22,6 +22,7 @@ const crypto = __importStar(require("crypto")); const fs = __importStar(require("fs")); const os = __importStar(require("os")); const path = __importStar(require("path")); +const retry = require("async-retry"); const semver = __importStar(require("semver")); // Translations between actions input and Julia arch names const osMap = { @@ -59,7 +60,15 @@ function calculateChecksum(file) { */ function getJuliaVersionInfo() { return __awaiter(this, void 0, void 0, function* () { - const versionsFile = yield tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json'); + // Occasionally the connection is reset for unknown reasons + // In those cases, retry the download + const versionsFile = yield retry((bail) => __awaiter(this, void 0, void 0, function* () { + return yield tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json'); + }), { + onRetry: (err) => { + core.debug(`Download of versions.json failed, trying again. Error: ${err}`); + } + }); return JSON.parse(fs.readFileSync(versionsFile).toString()); }); } @@ -146,7 +155,15 @@ function installJulia(versionInfo, version, arch) { const fileInfo = getFileInfo(versionInfo, version, arch); const downloadURL = getDownloadURL(fileInfo, version, arch); core.debug(`downloading Julia from ${downloadURL}`); - const juliaDownloadPath = yield tc.downloadTool(downloadURL); + // Occasionally the connection is reset for unknown reasons + // In those cases, retry the download + const juliaDownloadPath = yield retry((bail) => __awaiter(this, void 0, void 0, function* () { + return yield tc.downloadTool(downloadURL); + }), { + onRetry: (err) => { + core.debug(`Download of ${downloadURL} failed, trying again. Error: ${err}`); + } + }); // Verify checksum if (!version.endsWith('nightly')) { const checkSum = yield calculateChecksum(juliaDownloadPath); diff --git a/package-lock.json b/package-lock.json index 851603f..51bdd84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1384,6 +1384,15 @@ "@types/yargs": "^12.0.9" } }, + "@types/async-retry": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/async-retry/-/async-retry-1.4.2.tgz", + "integrity": "sha512-GUDuJURF0YiJZ+CBjNQA0+vbP/VHlJbB0sFqkzsV7EcOPRfurVonXpXKAt3w8qIjM1TEzpz6hc6POocPvHOS3w==", + "dev": true, + "requires": { + "@types/retry": "*" + } + }, "@types/babel__core": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.6.tgz", @@ -1471,6 +1480,12 @@ "integrity": "sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==", "dev": true }, + "@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, "@types/semver": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.0.1.tgz", @@ -1643,6 +1658,14 @@ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "dev": true }, + "async-retry": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", + "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", + "requires": { + "retry": "0.12.0" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -6046,6 +6069,11 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", diff --git a/package.json b/package.json index 63ec0e8..155849e 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,11 @@ "@actions/exec": "^1.0.0", "@actions/io": "^1.0.0", "@actions/tool-cache": "^1.0.0", + "async-retry": "^1.3.1", "semver": "^6.3.0" }, "devDependencies": { + "@types/async-retry": "^1.4.2", "@types/jest": "^24.0.13", "@types/node": "^12.12.7", "@types/semver": "^6.0.0", diff --git a/src/installer.ts b/src/installer.ts index ffd0f7b..336a645 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -6,6 +6,7 @@ import * as crypto from 'crypto' import * as fs from 'fs' import * as os from 'os' import * as path from 'path' +import retry = require('async-retry') import * as semver from 'semver' @@ -47,7 +48,15 @@ async function calculateChecksum(file: string): Promise { * @returns The content of the downloaded versions.json file as object. */ export async function getJuliaVersionInfo(): Promise { - const versionsFile = await tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json') + // Occasionally the connection is reset for unknown reasons + // In those cases, retry the download + const versionsFile = await retry(async (bail: Function) => { + return await tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json') + }, { + onRetry: (err: Error) => { + core.debug(`Download of versions.json failed, trying again. Error: ${err}`) + } + }) return JSON.parse(fs.readFileSync(versionsFile).toString()) } @@ -141,7 +150,17 @@ export async function installJulia(versionInfo, version: string, arch: string): const fileInfo = getFileInfo(versionInfo, version, arch) const downloadURL = getDownloadURL(fileInfo, version, arch) core.debug(`downloading Julia from ${downloadURL}`) - const juliaDownloadPath = await tc.downloadTool(downloadURL) + + // Occasionally the connection is reset for unknown reasons + // In those cases, retry the download + const juliaDownloadPath = await retry(async (bail: Function) => { + return await tc.downloadTool(downloadURL) + }, { + onRetry: (err: Error) => { + core.debug(`Download of ${downloadURL} failed, trying again. Error: ${err}`) + } + }) + // Verify checksum if (!version.endsWith('nightly')) {