Skip to content

Commit

Permalink
upgrade retry time
Browse files Browse the repository at this point in the history
  • Loading branch information
peze committed May 11, 2024
1 parent 510f133 commit 859cab7
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 20 deletions.
4 changes: 3 additions & 1 deletion src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ export class BaseError extends Error {
}
}

class ResponseError extends BaseError {
export class ResponseError extends BaseError {
code: string
statusCode: number
retryAfter: number
data: any
description: string
accessDeniedDetail: any
Expand All @@ -26,6 +27,7 @@ class ResponseError extends BaseError {
this.name = 'ResponseError';
this.data = map.data;
this.description = map.description;
this.retryAfter = map.retryAfter;
this.accessDeniedDetail = map.accessDeniedDetail;
if (this.data && this.data.statusCode) {
this.statusCode = Number(this.data.statusCode);
Expand Down
20 changes: 15 additions & 5 deletions src/retry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as $core from './core';
import * as $error from './error';
const MAX_DELAY_TIME = 120 * 1000;
const MIN_DELAY_TIME = 100;
export class BackoffPolicy{
policy: string;
constructor(option: {[key: string]: any}) {
Expand Down Expand Up @@ -116,11 +118,13 @@ export class RetryCondition {
backoff: BackoffPolicy;
exception: string[];
errorCode: string[];
maxDelay: number;
constructor(condition: {[key: string]: any}) {
this.maxAttempts = condition.maxAttempts;
this.backoff = condition.backoff && BackoffPolicy.newBackoffPolicy(condition.backoff);
this.exception = condition.exception;
this.errorCode = condition.errorCode;
this.maxDelay = condition.maxDelay;
}
}

Expand All @@ -146,7 +150,7 @@ export class RetryPolicyContext {
retriesAttempted: number;
httpRequest: $core.Request;
httpResponse: $core.Response;
exception: $error.BaseError;
exception: $error.ResponseError | $error.BaseError;
constructor(options: {[key: string]: any}) {
this.key = options.key;
this.retriesAttempted = options.retriesAttempted || 0;
Expand Down Expand Up @@ -183,18 +187,24 @@ export function shouldRetry(options: RetryOptions, ctx: RetryPolicyContext): boo
return false;
}

export function getBackoffDealy(options: RetryOptions, ctx: RetryPolicyContext): number {
export function getBackoffDelay(options: RetryOptions, ctx: RetryPolicyContext): number {
const ex = ctx.exception;
const conditions = options.retryCondition;
for(let i = 0; i < conditions.length; i++) {
const condition = conditions[i];
if(!condition.exception.includes(ex.name) && !condition.errorCode.includes(ex.code)) {
continue;
}
const maxDelay = condition.maxDelay || MAX_DELAY_TIME;
const retryAfter = (ctx.exception as $error.ResponseError).retryAfter;
if(retryAfter !== undefined) {
return Math.min(retryAfter, maxDelay);
}

if(!condition.backoff) {
return 100;
return MIN_DELAY_TIME;
}
return condition.backoff.getDelayTime(ctx);
return Math.min(condition.backoff.getDelayTime(ctx), maxDelay);
}
return 100;
return MIN_DELAY_TIME;
}
1 change: 1 addition & 0 deletions test/fixtures/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test For File
112 changes: 98 additions & 14 deletions test/retry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ describe('$dara retry', function () {
}
}

class CErr extends $dara.ResponseError {

constructor(map: { [key: string]: any }) {
super(map);
this.name = 'BErr';
}
}

it('init base backoff policy should not okay', function() {
try {
const err = new $dara.BackoffPolicy({});
Expand Down Expand Up @@ -139,7 +147,7 @@ describe('$dara retry', function () {
assert.deepStrictEqual($dara.shouldRetry(option, context), false);
});

it('getBackoffDealy should ok', async function () {
it('getBackoffDelay should ok', async function () {
const condition = new $dara.RetryCondition({
maxAttempts: 3,
exception: ['AErr'],
Expand All @@ -158,7 +166,7 @@ describe('$dara retry', function () {
})
});

assert.deepStrictEqual($dara.getBackoffDealy(option, context), 100);
assert.deepStrictEqual($dara.getBackoffDelay(option, context), 100);

context = new $dara.RetryPolicyContext({
retriesAttempted: 2,
Expand All @@ -168,7 +176,7 @@ describe('$dara retry', function () {
})
});

assert.deepStrictEqual($dara.getBackoffDealy(option, context), 100);
assert.deepStrictEqual($dara.getBackoffDelay(option, context), 100);

const fixedPolicy = $dara.BackoffPolicy.newBackoffPolicy({
policy: 'Fixed',
Expand All @@ -193,7 +201,7 @@ describe('$dara retry', function () {
});


assert.deepStrictEqual($dara.getBackoffDealy(option, context), 1000);
assert.deepStrictEqual($dara.getBackoffDelay(option, context), 1000);

const randomPolicy = $dara.BackoffPolicy.newBackoffPolicy({
policy: 'Random',
Expand All @@ -212,7 +220,7 @@ describe('$dara retry', function () {
retryCondition: [condition2]
});

assert.ok($dara.getBackoffDealy(option, context) < 10000);
assert.ok($dara.getBackoffDelay(option, context) < 10000);

const randomPolicy2 = $dara.BackoffPolicy.newBackoffPolicy({
policy: 'Random',
Expand All @@ -231,7 +239,7 @@ describe('$dara retry', function () {
retryCondition: [condition2Other]
});

assert.deepStrictEqual($dara.getBackoffDealy(option, context), 10);
assert.deepStrictEqual($dara.getBackoffDelay(option, context), 10);


let exponentialPolicy = $dara.BackoffPolicy.newBackoffPolicy({
Expand All @@ -251,7 +259,7 @@ describe('$dara retry', function () {
retryCondition: [condition3]
});

assert.deepStrictEqual($dara.getBackoffDealy(option, context), 1024);
assert.deepStrictEqual($dara.getBackoffDelay(option, context), 1024);

exponentialPolicy = $dara.BackoffPolicy.newBackoffPolicy({
policy: 'Exponential',
Expand All @@ -270,7 +278,7 @@ describe('$dara retry', function () {
retryCondition: [condition4]
});

assert.deepStrictEqual($dara.getBackoffDealy(option, context), 10000);
assert.deepStrictEqual($dara.getBackoffDelay(option, context), 10000);

let equalJitterPolicy = $dara.BackoffPolicy.newBackoffPolicy({
policy: 'EqualJitter',
Expand All @@ -279,7 +287,7 @@ describe('$dara retry', function () {
});

const condition5 = new $dara.RetryCondition({
maxAttempts: 3,
maxAttempts: 2,
exception: ['AErr'],
errorCode: ['A1Err'],
backoff: equalJitterPolicy,
Expand All @@ -288,7 +296,7 @@ describe('$dara retry', function () {
retryable: true,
retryCondition: [condition5]
});
let backoffTime = $dara.getBackoffDealy(option, context)
let backoffTime = $dara.getBackoffDelay(option, context)
assert.ok(backoffTime > 512 && backoffTime < 1024);

equalJitterPolicy = $dara.BackoffPolicy.newBackoffPolicy({
Expand All @@ -307,7 +315,7 @@ describe('$dara retry', function () {
retryable: true,
retryCondition: [condition6]
});
backoffTime = $dara.getBackoffDealy(option, context)
backoffTime = $dara.getBackoffDelay(option, context)
assert.ok(backoffTime > 5000 && backoffTime < 10000);


Expand All @@ -318,7 +326,7 @@ describe('$dara retry', function () {
});

const condition7 = new $dara.RetryCondition({
maxAttempts: 3,
maxAttempts: 2,
exception: ['AErr'],
errorCode: ['A1Err'],
backoff: fullJitterPolicy,
Expand All @@ -327,7 +335,7 @@ describe('$dara retry', function () {
retryable: true,
retryCondition: [condition7]
});
backoffTime = $dara.getBackoffDealy(option, context)
backoffTime = $dara.getBackoffDelay(option, context)
assert.ok(backoffTime >= 0 && backoffTime < 1024);

fullJitterPolicy = $dara.BackoffPolicy.newBackoffPolicy({
Expand All @@ -346,7 +354,83 @@ describe('$dara retry', function () {
retryable: true,
retryCondition: [condition8]
});
backoffTime = $dara.getBackoffDealy(option, context)
backoffTime = $dara.getBackoffDelay(option, context)
assert.ok(backoffTime >= 0 && backoffTime < 10000);

const condition9 = new $dara.RetryCondition({
maxAttempts: 3,
exception: ['AErr'],
errorCode: ['A1Err'],
backoff: fullJitterPolicy,
maxDelay: 1000,
});
option = new $dara.RetryOptions({
retryable: true,
retryCondition: [condition9]
});
backoffTime = $dara.getBackoffDelay(option, context)
assert.ok(backoffTime >= 0 && backoffTime <= 1000);


fullJitterPolicy = $dara.BackoffPolicy.newBackoffPolicy({
policy: 'ExponentialWithFullJitter',
period: 100,
cap: 10000 * 10000,
});

const condition12 = new $dara.RetryCondition({
maxAttempts: 2,
exception: ['AErr'],
errorCode: ['A1Err'],
backoff: fullJitterPolicy,
});
option = new $dara.RetryOptions({
retryable: true,
retryCondition: [condition12]
});
backoffTime = $dara.getBackoffDelay(option, context);
assert.ok(backoffTime >= 0 && backoffTime <= 120 * 1000);

context = new $dara.RetryPolicyContext({
retriesAttempted: 2,
exception: new CErr({
code: 'CErr',
message: 'c error',
retryAfter: 3000
})
});
const condition10 = new $dara.RetryCondition({
maxAttempts: 3,
exception: ['CErr'],
errorCode: ['CErr'],
backoff: fullJitterPolicy,
maxDelay: 5000,
});
option = new $dara.RetryOptions({
retryable: true,
retryCondition: [condition10]
});
backoffTime = $dara.getBackoffDelay(option, context)
assert.strictEqual(backoffTime, 3000);

const condition11 = new $dara.RetryCondition({
maxAttempts: 3,
exception: ['CErr'],
errorCode: ['CErr'],
backoff: fullJitterPolicy,
maxDelay: 1000,
});
option = new $dara.RetryOptions({
retryable: true,
retryCondition: [condition11]
});
backoffTime = $dara.getBackoffDelay(option, context)
assert.strictEqual(backoffTime, 1000);



});



});

0 comments on commit 859cab7

Please sign in to comment.