Skip to content
This repository was archived by the owner on Apr 10, 2025. It is now read-only.

Commit 6ad458f

Browse files
authored
Merge pull request #108 from semrush/retries-configuration
Possibility to configure action retries
2 parents 72affb8 + abfb0d0 commit 6ad458f

File tree

6 files changed

+60
-22
lines changed

6 files changed

+60
-22
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@semrush/purr",
3-
"version": "3.15.8",
3+
"version": "3.15.10",
44
"description": "",
55
"main": "src/cli.cjs",
66
"scripts": {

src/check/runner.js

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,6 @@ class CheckRunner {
180180

181181
result = result.then(async () => {
182182
const actionReport = new ActionReport(stepName, step, '***hidden***');
183-
const maxRetries = 5;
184-
const baseDelay = 1000;
185183

186184
// eslint-disable-next-line consistent-return
187185
const runAction = async (attempt = 1) => {
@@ -215,23 +213,24 @@ class CheckRunner {
215213
});
216214
}
217215
} catch (err) {
218-
const isResetError = err.message.includes('ERR_CONNECTION_RESET');
219-
const isClosedError = err.message.includes('ERR_CONNECTION_CLOSED');
220-
if (isResetError || isClosedError) {
221-
log.error('ERR_CONNECTION_* error occurred: ', err);
222-
}
223-
if ((isResetError || isClosedError) && attempt <= maxRetries) {
224-
const jitter = Math.random() * 1000;
225-
const delay = baseDelay * attempt + jitter;
226-
log.warn(
227-
`Retrying action '${stepName}' (Attempt ${attempt} of ${maxRetries}) after ${delay.toFixed(
228-
0
229-
)}ms due to connection issue.`
230-
);
231-
await new Promise((resolve) => {
232-
setTimeout(resolve, delay);
233-
});
234-
return runAction(attempt + 1);
216+
const isRetryableError = config.actionRetryErrors.some((item) =>
217+
err.message.includes(item)
218+
);
219+
if (isRetryableError) {
220+
log.error('Retryable error occurred: ', err);
221+
if (attempt <= config.actionRetryCount) {
222+
const jitter = Math.random() * 1000;
223+
const delay = config.actionRetryTimeout * attempt + jitter;
224+
log.warn(
225+
`Retrying action '${stepName}' (Attempt ${attempt} of ${config.actionRetryCount}) after ${delay.toFixed(
226+
0
227+
)}ms due to connection issue.`
228+
);
229+
await new Promise((resolve) => {
230+
setTimeout(resolve, delay);
231+
});
232+
return runAction(attempt + 1);
233+
}
235234
}
236235
actionReport.success = false;
237236
actionReport.shortMessage = err.message;

src/config/__tests__/configuration.test.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ describe('Test Configuration class', () => {
88
const configuration = new Configuration(envParams, rootDir);
99

1010
const defaultConfiguration = {
11+
actionRetryCount: 5,
12+
actionRetryErrors: ['ERR_CONNECTION_RESET', 'ERR_CONNECTION_CLOSED'],
13+
actionRetryTimeout: 1000,
1114
apiUrlPrefix: '/api/v1',
1215
apiWaitTimeout: 27000,
1316
artifactsDir: '/rootDir/storage',

src/config/configuration.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,18 @@ class Configuration {
200200
180000
201201
);
202202

203+
this.actionRetryErrors = getDefault(
204+
envParams.ACTION_RETRY_ERRORS,
205+
'ERR_CONNECTION_RESET,ERR_CONNECTION_CLOSED'
206+
)
207+
.split(',')
208+
.map((msg) => msg.trim())
209+
.filter((msg) => msg.length > 0);
210+
211+
this.actionRetryCount = getDefault(envParams.ACTION_RETRY_COUNT, 5);
212+
213+
this.actionRetryTimeout = getDefault(envParams.ACTION_RETRY_TIMEOUT, 1000);
214+
203215
if (this.artifactsGroupByCheckName && isUndefined(this.artifactsDir)) {
204216
throw new Error(
205217
'Enabled group artifacts by check name and artifacts path not specified'

src/config/env.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,30 @@ const DEFAULT_ENV_PARAMS = {
233233
* @default {180000}
234234
*/
235235
BROWSER_PROTOCOL_TIMEOUT: 180000,
236+
237+
/**
238+
* Check action retry comma-separated errors list (checked by err.message.includes())
239+
*
240+
* @type string
241+
* @default ERR_CONNECTION_RESET,ERR_CONNECTION_CLOSED
242+
*/
243+
ACTION_RETRY_ERRORS: 'ERR_CONNECTION_RESET,ERR_CONNECTION_CLOSED',
244+
245+
/**
246+
* Check action retry count
247+
*
248+
* @type number
249+
* @default 5
250+
*/
251+
ACTION_RETRY_COUNT: 5,
252+
253+
/**
254+
* Check action retry timeout (ms)
255+
*
256+
* @type number
257+
* @default 1000
258+
*/
259+
ACTION_RETRY_TIMEOUT: 1000,
236260
};
237261

238262
class EnvParams {

0 commit comments

Comments
 (0)