From 8e1ba7e3e71cbbbf47a0af23e6f5035059fe07ed Mon Sep 17 00:00:00 2001 From: Jong-hoon Oh Date: Mon, 12 Oct 2020 15:03:34 +0900 Subject: [PATCH] fix: retry on stale ETag --- index.js | 68 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/index.js b/index.js index c4c831d..639c5cf 100644 --- a/index.js +++ b/index.js @@ -27,35 +27,55 @@ class ServerlessLambdaEdgePreExistingCloudFront { for (let idx = 0; idx < events.length; idx += 1) { const event = events[idx] const functionArn = await this.getlatestVersionLambdaArn(functionObj.name) - const config = await this.provider.request('CloudFront', 'getDistribution', { - Id: event.preExistingCloudFront.distributionId - }) - - if (event.preExistingCloudFront.pathPattern === '*') { - config.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations = await this.associateFunction( - config.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations, - event, - functionObj.name, - functionArn - ) - } else { - config.DistributionConfig.CacheBehaviors = await this.associateNonDefaultCacheBehaviors( - config.DistributionConfig.CacheBehaviors, - event, - functionObj.name, - functionArn - ) - } this.serverless.cli.consoleLog( `${functionArn} is associating to ${event.preExistingCloudFront.distributionId} CloudFront Distribution. waiting for deployed status.` ) - await this.provider.request('CloudFront', 'updateDistribution', { - Id: event.preExistingCloudFront.distributionId, - IfMatch: config.ETag, - DistributionConfig: config.DistributionConfig - }) + let retryCount = 5 + + const updateDistribution = async () => { + const config = await this.provider.request('CloudFront', 'getDistribution', { + Id: event.preExistingCloudFront.distributionId + }) + + if (event.preExistingCloudFront.pathPattern === '*') { + config.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations = await this.associateFunction( + config.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations, + event, + functionObj.name, + functionArn + ) + } else { + config.DistributionConfig.CacheBehaviors = await this.associateNonDefaultCacheBehaviors( + config.DistributionConfig.CacheBehaviors, + event, + functionObj.name, + functionArn + ) + } + + await this.provider + .request('CloudFront', 'updateDistribution', { + Id: event.preExistingCloudFront.distributionId, + IfMatch: config.ETag, + DistributionConfig: config.DistributionConfig + }) + .catch(async (error) => { + if (error.providerError.code === 'PreconditionFailed' && retryCount > 0) { + this.serverless.cli.consoleLog( + `received precondition failed error, retrying... (${retryCount}/5)` + ) + retryCount -= 1 + await new Promise((res) => setTimeout(res, 5000)) + return updateDistribution() + } + this.serverless.cli.consoleLog(error) + throw error + }) + } + + await updateDistribution() } }) }, Promise.resolve())