Merge pull request #757 from Budibase/cloudfront-issues

Fixing some issues experienced with Cloudfront invalidations
This commit is contained in:
Michael Drury 2020-10-19 16:13:50 +01:00 committed by GitHub
commit 2f9ea036a1
6 changed files with 76 additions and 5 deletions

View File

@ -4,4 +4,12 @@
export let size = "60"
</script>
<div class="spinner-container">
<Circle {size} color="#000000" unit="px" />
</div>
<style>
.spinner-container {
display: block;
}
</style>

View File

@ -1,5 +1,6 @@
<script>
import { onMount, onDestroy } from "svelte"
import Spinner from "components/common/Spinner.svelte"
import { slide } from "svelte/transition"
import { Heading, Body } from "@budibase/bbui"
import api from "builderStore/api"
@ -66,8 +67,13 @@
{formatDate(deployment.updatedAt, 'timeOnly')}
</span>
</div>
<div class={`deployment-status ${deployment.status}`}>
{deployment.status}
<div class="deployment-right">
{#if deployment.status.toLowerCase() === "pending"}
<Spinner size="10" />
{/if}
<div class={`deployment-status ${deployment.status}`}>
{deployment.status}
</div>
</div>
</article>
{/each}
@ -126,6 +132,13 @@
font-size: var(--font-size-s);
}
.deployment-right {
display: flex;
flex-direction: row;
gap: 16px;
align-items: center;
}
.deployment-status {
font-size: var(--font-size-s);
padding: var(--spacing-s);

View File

@ -1,5 +1,6 @@
const fs = require("fs")
const { join } = require("../../../utilities/centralPath")
let { wait } = require("../../../utilities")
const AWS = require("aws-sdk")
const fetch = require("node-fetch")
const uuid = require("uuid")
@ -7,10 +8,15 @@ const { budibaseAppsDir } = require("../../../utilities/budibaseDir")
const PouchDB = require("../../../db")
const environment = require("../../../environment")
const MAX_INVALIDATE_WAIT_MS = 120000
const INVALIDATE_WAIT_PERIODS_MS = 5000
// export so main deploy functions can use too
exports.MAX_INVALIDATE_WAIT_MS = MAX_INVALIDATE_WAIT_MS
async function invalidateCDN(cfDistribution, appId) {
const cf = new AWS.CloudFront({})
return cf
const resp = await cf
.createInvalidation({
DistributionId: cfDistribution,
InvalidationBatch: {
@ -22,6 +28,28 @@ async function invalidateCDN(cfDistribution, appId) {
},
})
.promise()
let totalWaitTimeMs = 0
let complete = false
do {
try {
const state = await cf
.getInvalidation({
DistributionId: cfDistribution,
Id: resp.Invalidation.Id,
})
.promise()
if (state.Invalidation.Status === "Completed") {
complete = true
}
} catch (err) {
console.log()
}
await wait(INVALIDATE_WAIT_PERIODS_MS)
totalWaitTimeMs += INVALIDATE_WAIT_PERIODS_MS
} while (totalWaitTimeMs <= MAX_INVALIDATE_WAIT_MS && !complete)
if (!complete) {
throw "Unable to invalidate old app version"
}
}
exports.updateDeploymentQuota = async function(quota) {

View File

@ -4,10 +4,17 @@ const {
uploadAppAssets,
verifyDeployment,
updateDeploymentQuota,
MAX_INVALIDATE_WAIT_MS,
} = require("./aws")
const { DocumentTypes, SEPARATOR, UNICODE_MAX } = require("../../../db/utils")
const newid = require("../../../db/newid")
const DeploymentStatus = {
SUCCESS: "SUCCESS",
PENDING: "PENDING",
FAILURE: "FAILURE",
}
function replicate(local, remote) {
return new Promise((resolve, reject) => {
const replication = local.sync(remote)
@ -137,6 +144,20 @@ exports.fetchDeployments = async function(ctx) {
try {
const db = new PouchDB(ctx.user.instanceId)
const deploymentDoc = await db.get("_local/deployments")
// check that no deployments have crashed etc and are now stuck
let changed = false
for (let deployment of Object.values(deploymentDoc.history)) {
if (
deployment.status === DeploymentStatus.PENDING &&
Date.now() - deployment.updatedAt > MAX_INVALIDATE_WAIT_MS
) {
deployment.status = DeploymentStatus.FAILURE
changed = true
}
}
if (changed) {
await db.put(deploymentDoc)
}
ctx.body = Object.values(deploymentDoc.history).reverse()
} catch (err) {
ctx.body = []

View File

@ -1,4 +1,4 @@
const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
let { wait } = require("../../utilities")
module.exports.definition = {
name: "Delay",

View File

@ -0,0 +1 @@
exports.wait = ms => new Promise(resolve => setTimeout(resolve, ms))