Skip to content

Commit c5caafe

Browse files
retry logic
1 parent c67fa74 commit c5caafe

File tree

2 files changed

+116
-27
lines changed

2 files changed

+116
-27
lines changed

dist/setup/index.js

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97299,7 +97299,6 @@ async function installGraalPy(graalpyVersion, architecture, allowPreReleases, re
9729997299
}
9730097300
let releaseData = findRelease(releases, graalpyVersion, architecture, false);
9730197301
if (allowPreReleases && (!releaseData || !releaseData.foundAsset)) {
97302-
// check for pre-release
9730397302
core.info([
9730497303
`Stable GraalPy version ${graalpyVersion} with arch ${architecture} not found`,
9730597304
`Trying pre-release versions`
@@ -97321,8 +97320,7 @@ async function installGraalPy(graalpyVersion, architecture, allowPreReleases, re
9732197320
else {
9732297321
downloadDir = await tc.extractTar(graalpyPath);
9732397322
}
97324-
// root folder in archive can have unpredictable name so just take the first folder
97325-
// downloadDir is unique folder under TEMP and can't contain any other folders
97323+
// folder name in archive is unpredictable
9732697324
const archiveName = fs_1.default.readdirSync(downloadDir)[0];
9732797325
const toolDir = path.join(downloadDir, archiveName);
9732897326
let installDir = toolDir;
@@ -97336,17 +97334,54 @@ async function installGraalPy(graalpyVersion, architecture, allowPreReleases, re
9733697334
}
9733797335
catch (err) {
9733897336
if (err instanceof Error) {
97339-
// Rate limit?
97340-
if (err instanceof tc.HTTPError &&
97341-
(err.httpStatusCode === 403 || err.httpStatusCode === 429)) {
97342-
core.info(`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`);
97343-
}
97344-
else {
97345-
core.info(err.message);
97337+
const isRateLimit = err instanceof tc.HTTPError &&
97338+
(err.httpStatusCode === 403 || err.httpStatusCode === 429);
97339+
if (isRateLimit) {
97340+
core.warning(`Rate limit or restricted access response received: HTTP ${err.httpStatusCode}`);
97341+
let lastStatus;
97342+
for (let attempt = 1; attempt <= 3; attempt++) {
97343+
core.info(`Retry attempt ${attempt} of 3 due to rate limit...`);
97344+
await new Promise(res => setTimeout(res, 2000 * attempt));
97345+
try {
97346+
const retryPath = await tc.downloadTool(downloadUrl, undefined, AUTH);
97347+
core.info(`Retry succeeded.`);
97348+
// Extract retry archive
97349+
let retryExtractDir;
97350+
if (utils_1.IS_WINDOWS) {
97351+
retryExtractDir = await tc.extractZip(retryPath);
97352+
}
97353+
else {
97354+
retryExtractDir = await tc.extractTar(retryPath);
97355+
}
97356+
const archiveName = fs_1.default.readdirSync(retryExtractDir)[0];
97357+
const toolDir = path.join(retryExtractDir, archiveName);
97358+
let installDir = toolDir;
97359+
if (!(0, utils_1.isNightlyKeyword)(resolvedGraalPyVersion)) {
97360+
installDir = await tc.cacheDir(toolDir, 'GraalPy', resolvedGraalPyVersion, architecture);
97361+
}
97362+
const binaryPath = path.join(installDir, 'bin');
97363+
await createGraalPySymlink(binaryPath, resolvedGraalPyVersion);
97364+
await installPip(binaryPath);
97365+
return { installDir, resolvedGraalPyVersion };
97366+
}
97367+
catch (retryErr) {
97368+
if (retryErr instanceof tc.HTTPError) {
97369+
lastStatus = retryErr.httpStatusCode;
97370+
core.warning(`Retry ${attempt} failed. HTTP ${lastStatus}`);
97371+
}
97372+
else {
97373+
core.warning(`Retry ${attempt} failed: ${retryErr}`);
97374+
}
97375+
if (attempt === 3) {
97376+
core.error(`All retries failed. Last HTTP status code: ${lastStatus ?? 'unknown'}`);
97377+
throw retryErr;
97378+
}
97379+
}
97380+
}
9734697381
}
97347-
if (err.stack !== undefined) {
97382+
core.info(err.message);
97383+
if (err.stack)
9734897384
core.debug(err.stack);
97349-
}
9735097385
}
9735197386
throw err;
9735297387
}

src/install-graalpy.ts

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export async function installGraalPy(
3838
let releaseData = findRelease(releases, graalpyVersion, architecture, false);
3939

4040
if (allowPreReleases && (!releaseData || !releaseData.foundAsset)) {
41-
// check for pre-release
4241
core.info(
4342
[
4443
`Stable GraalPy version ${graalpyVersion} with arch ${architecture} not found`,
@@ -69,12 +68,11 @@ export async function installGraalPy(
6968
downloadDir = await tc.extractTar(graalpyPath);
7069
}
7170

72-
// root folder in archive can have unpredictable name so just take the first folder
73-
// downloadDir is unique folder under TEMP and can't contain any other folders
71+
// folder name in archive is unpredictable
7472
const archiveName = fs.readdirSync(downloadDir)[0];
75-
7673
const toolDir = path.join(downloadDir, archiveName);
7774
let installDir = toolDir;
75+
7876
if (!isNightlyKeyword(resolvedGraalPyVersion)) {
7977
installDir = await tc.cacheDir(
8078
toolDir,
@@ -91,21 +89,77 @@ export async function installGraalPy(
9189
return {installDir, resolvedGraalPyVersion};
9290
} catch (err) {
9391
if (err instanceof Error) {
94-
// Rate limit?
95-
if (
92+
const isRateLimit =
9693
err instanceof tc.HTTPError &&
97-
(err.httpStatusCode === 403 || err.httpStatusCode === 429)
98-
) {
99-
core.info(
100-
`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`
94+
(err.httpStatusCode === 403 || err.httpStatusCode === 429);
95+
96+
if (isRateLimit) {
97+
core.warning(
98+
`Rate limit or restricted access response received: HTTP ${err.httpStatusCode}`
10199
);
102-
} else {
103-
core.info(err.message);
104-
}
105-
if (err.stack !== undefined) {
106-
core.debug(err.stack);
100+
101+
let lastStatus: number | undefined;
102+
103+
for (let attempt = 1; attempt <= 3; attempt++) {
104+
core.info(`Retry attempt ${attempt} of 3 due to rate limit...`);
105+
await new Promise(res => setTimeout(res, 2000 * attempt));
106+
107+
try {
108+
const retryPath = await tc.downloadTool(
109+
downloadUrl,
110+
undefined,
111+
AUTH
112+
);
113+
core.info(`Retry succeeded.`);
114+
115+
// Extract retry archive
116+
let retryExtractDir;
117+
if (IS_WINDOWS) {
118+
retryExtractDir = await tc.extractZip(retryPath);
119+
} else {
120+
retryExtractDir = await tc.extractTar(retryPath);
121+
}
122+
123+
const archiveName = fs.readdirSync(retryExtractDir)[0];
124+
const toolDir = path.join(retryExtractDir, archiveName);
125+
let installDir = toolDir;
126+
127+
if (!isNightlyKeyword(resolvedGraalPyVersion)) {
128+
installDir = await tc.cacheDir(
129+
toolDir,
130+
'GraalPy',
131+
resolvedGraalPyVersion,
132+
architecture
133+
);
134+
}
135+
136+
const binaryPath = path.join(installDir, 'bin');
137+
await createGraalPySymlink(binaryPath, resolvedGraalPyVersion);
138+
await installPip(binaryPath);
139+
140+
return {installDir, resolvedGraalPyVersion};
141+
} catch (retryErr) {
142+
if (retryErr instanceof tc.HTTPError) {
143+
lastStatus = retryErr.httpStatusCode;
144+
core.warning(`Retry ${attempt} failed. HTTP ${lastStatus}`);
145+
} else {
146+
core.warning(`Retry ${attempt} failed: ${retryErr}`);
147+
}
148+
149+
if (attempt === 3) {
150+
core.error(
151+
`All retries failed. Last HTTP status code: ${lastStatus ?? 'unknown'}`
152+
);
153+
throw retryErr;
154+
}
155+
}
156+
}
107157
}
158+
159+
core.info(err.message);
160+
if (err.stack) core.debug(err.stack);
108161
}
162+
109163
throw err;
110164
}
111165
}

0 commit comments

Comments
 (0)