Skip to content

Commit

Permalink
feat: add retry count parameter to function uploads (#4841)
Browse files Browse the repository at this point in the history
* feat: add retry count parameter to function uploads

* chore: add newline

* chore: add test

* refactor: use retry count from backoff library

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
eduardoboucas and kodiakhq[bot] committed Jul 22, 2022
1 parent 5b112e3 commit e917f69
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 12 deletions.
31 changes: 19 additions & 12 deletions src/utils/deploy/upload-files.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,20 @@ const uploadFiles = async (api, deployId, uploadList, { concurrentUpload, maxRet
break
}
case 'function': {
response = await await retryUpload(
() =>
api.uploadDeployFunction({
body: readStreamCtor,
deployId,
name: encodeURI(normalizedPath),
runtime,
}),
maxRetry,
)
response = await retryUpload((retryCount) => {
const params = {
body: readStreamCtor,
deployId,
name: encodeURI(normalizedPath),
runtime,
}

if (retryCount > 0) {
params.xNfRetryCount = retryCount
}

return api.uploadDeployFunction(params)
}, maxRetry)
break
}
default: {
Expand All @@ -71,18 +75,21 @@ const uploadFiles = async (api, deployId, uploadList, { concurrentUpload, maxRet
const retryUpload = (uploadFn, maxRetry) =>
new Promise((resolve, reject) => {
let lastError

const fibonacciBackoff = backoff.fibonacci({
randomisationFactor: UPLOAD_RANDOM_FACTOR,
initialDelay: UPLOAD_INITIAL_DELAY,
maxDelay: UPLOAD_MAX_DELAY,
})

const tryUpload = async () => {
const tryUpload = async (retryIndex = -1) => {
try {
const results = await uploadFn()
const results = await uploadFn(retryIndex + 1)

return resolve(results)
} catch (error) {
lastError = error

// observed errors: 408, 401 (4** swallowed), 502
if (error.status >= 400 || error.name === 'FetchError') {
fibonacciBackoff.backoff()
Expand Down
41 changes: 41 additions & 0 deletions tests/unit/utils/deploy/upload-files.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const test = require('ava')
const sinon = require('sinon')
const { v4: generateUUID } = require('uuid')

const { uploadFiles } = require('../../../../src/utils/deploy/upload-files')

test('Adds a retry count to function upload requests', async (t) => {
const uploadDeployFunction = sinon.stub()
const mockError = new Error('Uh-oh')

mockError.status = 500

uploadDeployFunction.onCall(0).throws(mockError)
uploadDeployFunction.onCall(1).throws(mockError)
uploadDeployFunction.onCall(2).resolves()

const mockApi = {
uploadDeployFunction,
}
const deployId = generateUUID()
const files = [
{
assetType: 'function',
filepath: '/some/path/func1.zip',
normalizedPath: 'func1.zip',
runtime: 'js',
},
]
const options = {
concurrentUpload: 1,
maxRetry: 3,
statusCb: sinon.stub(),
}

await uploadFiles(mockApi, deployId, files, options)

t.is(uploadDeployFunction.callCount, 3)
t.is(uploadDeployFunction.firstCall.args[0].xNfRetryCount, undefined)
t.is(uploadDeployFunction.secondCall.args[0].xNfRetryCount, 1)
t.is(uploadDeployFunction.thirdCall.args[0].xNfRetryCount, 2)
})

1 comment on commit e917f69

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📊 Benchmark results

Package size: 222 MB

Please sign in to comment.