Skip to content

Commit 6d53abe

Browse files
author
Spencer
authored
[6.8] [kbn/es] auto retry snapshot download on unexpected errors (#38944) (#38994)
* [kbn/es] auto retry snapshot download on unexpected errors * missed an await * pass log to retry()
1 parent 5caf5da commit 6d53abe

File tree

1 file changed

+52
-26
lines changed

1 file changed

+52
-26
lines changed

packages/kbn-es/src/artifact.js

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const asyncPipeline = promisify(pipeline);
3131
const V1_VERSIONS_API = 'https://artifacts-api.elastic.co/v1/versions';
3232

3333
const { cache } = require('./utils');
34-
const { createCliError } = require('./errors');
34+
const { createCliError, isCliError } = require('./errors');
3535

3636
const TEST_ES_SNAPSHOT_VERSION = process.env.TEST_ES_SNAPSHOT_VERSION
3737
? process.env.TEST_ES_SNAPSHOT_VERSION
@@ -66,6 +66,25 @@ function headersToString(headers, indent = '') {
6666
);
6767
}
6868

69+
async function retry(log, fn) {
70+
async function doAttempt(attempt) {
71+
try {
72+
return await fn();
73+
} catch (error) {
74+
if (isCliError(error) || attempt >= 5) {
75+
throw error;
76+
}
77+
78+
log.warning('...failure, retrying in 5 seconds:', error.message);
79+
await new Promise(resolve => setTimeout(resolve, 5000));
80+
log.info('...retrying');
81+
return await doAttempt(attempt + 1);
82+
}
83+
}
84+
85+
return await doAttempt(1);
86+
}
87+
6988
exports.Artifact = class Artifact {
7089
/**
7190
* Fetch an Artifact from the Artifact API for a license level and version
@@ -78,22 +97,27 @@ exports.Artifact = class Artifact {
7897
const urlBuild = encodeURIComponent(TEST_ES_SNAPSHOT_VERSION);
7998
const url = `${V1_VERSIONS_API}/${urlVersion}/builds/${urlBuild}/projects/elasticsearch`;
8099

81-
log.info('downloading artifact info from %s', chalk.bold(url));
82-
const abc = new AbortController();
83-
const resp = await fetch(url, { signal: abc.signal });
84-
const json = await resp.text();
100+
const json = await retry(log, async () => {
101+
log.info('downloading artifact info from %s', chalk.bold(url));
85102

86-
if (resp.status === 404) {
87-
abc.abort();
88-
throw createCliError(
89-
`Snapshots for ${version}/${TEST_ES_SNAPSHOT_VERSION} are not available`
90-
);
91-
}
103+
const abc = new AbortController();
104+
const resp = await fetch(url, { signal: abc.signal });
105+
const json = await resp.text();
92106

93-
if (!resp.ok) {
94-
abc.abort();
95-
throw new Error(`Unable to read artifact info from ${url}: ${resp.statusText}\n ${json}`);
96-
}
107+
if (resp.status === 404) {
108+
abc.abort();
109+
throw createCliError(
110+
`Snapshots for ${version}/${TEST_ES_SNAPSHOT_VERSION} are not available`
111+
);
112+
}
113+
114+
if (!resp.ok) {
115+
abc.abort();
116+
throw new Error(`Unable to read artifact info from ${url}: ${resp.statusText}\n ${json}`);
117+
}
118+
119+
return json;
120+
});
97121

98122
// parse the api response into an array of Artifact objects
99123
const {
@@ -184,21 +208,23 @@ exports.Artifact = class Artifact {
184208
* @return {Promise<void>}
185209
*/
186210
async download(dest) {
187-
const cacheMeta = cache.readMeta(dest);
188-
const tmpPath = `${dest}.tmp`;
211+
await retry(this._log, async () => {
212+
const cacheMeta = cache.readMeta(dest);
213+
const tmpPath = `${dest}.tmp`;
189214

190-
const artifactResp = await this._download(tmpPath, cacheMeta.etag, cacheMeta.ts);
191-
if (artifactResp.cached) {
192-
return;
193-
}
215+
const artifactResp = await this._download(tmpPath, cacheMeta.etag, cacheMeta.ts);
216+
if (artifactResp.cached) {
217+
return;
218+
}
194219

195-
await this._verifyChecksum(artifactResp);
220+
await this._verifyChecksum(artifactResp);
196221

197-
// cache the etag for future downloads
198-
cache.writeMeta(dest, { etag: artifactResp.etag });
222+
// cache the etag for future downloads
223+
cache.writeMeta(dest, { etag: artifactResp.etag });
199224

200-
// rename temp download to the destination location
201-
fs.renameSync(tmpPath, dest);
225+
// rename temp download to the destination location
226+
fs.renameSync(tmpPath, dest);
227+
});
202228
}
203229

204230
/**

0 commit comments

Comments
 (0)