-
Notifications
You must be signed in to change notification settings - Fork 578
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: retry when net err or timeout (#876)
* feat: retry when net err or timeout * test: should not retry when params.stream is not readable * test: retry in browser Co-authored-by: beajer <919060679@qq.com>
- Loading branch information
Showing
9 changed files
with
269 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export declare function retry(this: any, func: Function, retryMax: number, config?: any): (...arg: any[]) => Promise<unknown>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.retry = void 0; | ||
function retry(func, retryMax, config = {}) { | ||
let retryNum = 0; | ||
const { retryDelay = 500, errorHandler = () => true } = config; | ||
const funcR = (...arg) => { | ||
return new Promise((resolve, reject) => { | ||
func(...arg) | ||
.then(result => { | ||
retryNum = 0; | ||
resolve(result); | ||
}) | ||
.catch(err => { | ||
if (retryNum < retryMax && errorHandler(err)) { | ||
retryNum++; | ||
setTimeout(() => { | ||
resolve(funcR(...arg)); | ||
}, retryDelay); | ||
} | ||
else { | ||
retryNum = 0; | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
}; | ||
return funcR; | ||
} | ||
exports.retry = retry; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
export function retry(this: any, func: Function, retryMax: number, config: any = {}) { | ||
let retryNum = 0; | ||
const { retryDelay = 500, errorHandler = () => true } = config; | ||
const funcR = (...arg) => { | ||
return new Promise((resolve, reject) => { | ||
func(...arg) | ||
.then(result => { | ||
retryNum = 0; | ||
resolve(result); | ||
}) | ||
.catch(err => { | ||
if (retryNum < retryMax && errorHandler(err)) { | ||
retryNum++; | ||
setTimeout(() => { | ||
resolve(funcR(...arg)); | ||
}, retryDelay); | ||
} else { | ||
retryNum = 0; | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
}; | ||
|
||
return funcR; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
const assert = require('assert'); | ||
const OSS = require('../../..'); | ||
const config = require('../../config').oss; | ||
const utils = require('../utils'); | ||
const { md5 } = require('utility'); | ||
const mm = require('mm'); | ||
const fs = require('fs'); | ||
const { after } = require('mocha'); | ||
|
||
describe('test/retry.test.js', () => { | ||
let store; | ||
const RETRY_MAX = 3; | ||
let testRetryCount = 0; | ||
let autoRestoreWhenRETRY_LIMIE = true; | ||
const bucket = `ali-oss-test-bucket-${utils.prefix.replace(/[/.]/g, '-').replace(/-$/, '')}`; | ||
before(async () => { | ||
store = new OSS({ | ||
...config, | ||
retryMax: RETRY_MAX, | ||
requestErrorRetryHandle: () => { | ||
testRetryCount++; | ||
if (testRetryCount === RETRY_MAX && autoRestoreWhenRETRY_LIMIE) { | ||
mm.restore(); | ||
} | ||
return true; | ||
} | ||
}); | ||
const result = await store.putBucket(bucket); | ||
assert.strictEqual(result.bucket, bucket); | ||
assert.strictEqual(result.res.status, 200); | ||
store.useBucket(bucket); | ||
}); | ||
beforeEach(() => { | ||
testRetryCount = 0; | ||
autoRestoreWhenRETRY_LIMIE = true; | ||
mm.error(store.urllib, 'request', { | ||
status: -1, // timeout | ||
headers: {}, | ||
}); | ||
}); | ||
afterEach(() => { | ||
mm.restore(); | ||
}); | ||
after(async () => { | ||
await utils.cleanBucket(store, bucket); | ||
}); | ||
|
||
it('set retryMax to test request auto retry when networkError or timeout', async () => { | ||
const res = await store.listBuckets(); | ||
assert.strictEqual(res.res.status, 200); | ||
assert.strictEqual(testRetryCount, RETRY_MAX); | ||
}); | ||
|
||
it('should throw when retry count bigger than options retryMax', async () => { | ||
autoRestoreWhenRETRY_LIMIE = false; | ||
try { | ||
await store.listBuckets(); | ||
assert(false, 'should throw error'); | ||
} catch (error) { | ||
assert(error.status === -1); | ||
} | ||
}); | ||
|
||
it('should succeed when put with filename', async () => { | ||
const name = `ali-oss-test-retry-file-${Date.now()}`; | ||
const fileName = await utils.createTempFile(name, 1 * 1024); | ||
const res = await store.put(name, fileName); | ||
assert.strictEqual(res.res.status, 200); | ||
assert.strictEqual(testRetryCount, RETRY_MAX); | ||
const onlineFile = await store.get(name); | ||
assert.strictEqual(md5(fs.readFileSync(fileName)), md5(onlineFile.content)); | ||
}); | ||
|
||
it('should fail when putStream', async () => { | ||
autoRestoreWhenRETRY_LIMIE = false; | ||
const name = `ali-oss-test-retry-file-${Date.now()}`; | ||
const fileName = await utils.createTempFile(name, 1 * 1024); | ||
try { | ||
await store.putStream(name, fs.createReadStream(fileName)); | ||
assert(false, 'should not reach here'); | ||
} catch (e) { | ||
assert.strictEqual(e.status, -1); | ||
} | ||
}); | ||
|
||
}); |