1
0
mirror of synced 2025-12-21 10:57:10 -05:00

Move delay for Heroku Preboot to before marking deployment successful (#21736)

* Move delay for Heroku Preboot from post-deploy to pre-success

* Shorten arbitrary delay before first Fastly purge
This commit is contained in:
James M. Greene
2021-09-24 19:35:13 -05:00
committed by GitHub
parent 433b3afd53
commit a76f30e5f2
3 changed files with 22 additions and 25 deletions

View File

@@ -129,9 +129,10 @@ jobs:
HYDRO_ENDPOINT: ${{ secrets.HYDRO_ENDPOINT }} HYDRO_ENDPOINT: ${{ secrets.HYDRO_ENDPOINT }}
HYDRO_SECRET: ${{ secrets.HYDRO_SECRET }} HYDRO_SECRET: ${{ secrets.HYDRO_SECRET }}
SOURCE_BLOB_URL: ${{ steps.build-source.outputs.download_url }} SOURCE_BLOB_URL: ${{ steps.build-source.outputs.download_url }}
DELAY_FOR_PREBOOT: 'true'
with: with:
script: | script: |
const { GITHUB_TOKEN, HEROKU_API_TOKEN, SOURCE_BLOB_URL } = process.env const { GITHUB_TOKEN, HEROKU_API_TOKEN, SOURCE_BLOB_URL, DELAY_FOR_PREBOOT } = process.env
// Exit if GitHub Actions PAT is not found // Exit if GitHub Actions PAT is not found
if (!GITHUB_TOKEN) { if (!GITHUB_TOKEN) {
@@ -158,6 +159,7 @@ jobs:
try { try {
await deployToProduction({ await deployToProduction({
octokit, octokit,
includeDelayForPreboot: DELAY_FOR_PREBOOT !== 'false',
// These parameters will ONLY be set by Actions // These parameters will ONLY be set by Actions
sourceBlobUrl: SOURCE_BLOB_URL, sourceBlobUrl: SOURCE_BLOB_URL,
runId: context.runId runId: context.runId
@@ -205,7 +207,6 @@ jobs:
FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }} FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }}
FASTLY_SERVICE_ID: ${{ secrets.FASTLY_SERVICE_ID }} FASTLY_SERVICE_ID: ${{ secrets.FASTLY_SERVICE_ID }}
FASTLY_SURROGATE_KEY: 'all-the-things' FASTLY_SURROGATE_KEY: 'all-the-things'
DELAY_FOR_PREBOOT: 'true'
with: with:
script: | script: |
// Workaround to allow us to load ESM files with `require(...)` // Workaround to allow us to load ESM files with `require(...)`
@@ -215,9 +216,7 @@ jobs:
const { default: purgeEdgeCache } = require('./script/deployment/purge-edge-cache') const { default: purgeEdgeCache } = require('./script/deployment/purge-edge-cache')
try { try {
await purgeEdgeCache({ await purgeEdgeCache()
includeDelayForPreboot: process.env.DELAY_FOR_PREBOOT !== 'false'
})
} catch (error) { } catch (error) {
console.error(`Failed to purge the edge cache: ${error.message}`) console.error(`Failed to purge the edge cache: ${error.message}`)
console.error(error) console.error(error)

View File

@@ -6,6 +6,7 @@ import { setOutput } from '@actions/core'
const SLEEP_INTERVAL = 5000 const SLEEP_INTERVAL = 5000
const HEROKU_LOG_LINES_TO_SHOW = 25 const HEROKU_LOG_LINES_TO_SHOW = 25
const DELAY_FOR_PREBOOT_SWAP = 135000 // 2:15
// Allow for a few 404 (Not Found) or 429 (Too Many Requests) responses from the // Allow for a few 404 (Not Found) or 429 (Too Many Requests) responses from the
// semi-unreliable Heroku API when we're polling for status updates // semi-unreliable Heroku API when we're polling for status updates
@@ -13,6 +14,7 @@ const ALLOWED_MISSING_RESPONSE_COUNT = 5
export default async function deployToProduction({ export default async function deployToProduction({
octokit, octokit,
includeDelayForPreboot = true,
// These parameters will only be set by Actions // These parameters will only be set by Actions
sourceBlobUrl = null, sourceBlobUrl = null,
runId = null, runId = null,
@@ -332,11 +334,20 @@ export default async function deployToProduction({
)} seconds.` )} seconds.`
) )
// // IMPORTANT:
// TODO: // If Heroku Preboot is enabled, then there is an additional delay of at
// Should we consider adding an explicit 2-minute pause here to allow for // least 2 minutes before the new dynos are swapped into active serving.
// Heroku Preboot to actually swap in the new dynos? // If we move off Heroku in the future, this should be revisited and
// // updated/removed as relevant to align with the new hosting platform.
if (includeDelayForPreboot) {
console.log(`Waiting for Heroku Preboot to swap dynos (${DELAY_FOR_PREBOOT_SWAP} ms)...`)
await sleep(DELAY_FOR_PREBOOT_SWAP)
// TODO:
// Is there a faster alternative than this arbitrary delay? For example,
// is there some Heroku API we can query to see when this release is
// considered to be the live one, or when the old dynos are shut down?
}
// Report success! // Report success!
const successMessage = `Deployment succeeded after ${Math.round( const successMessage = `Deployment succeeded after ${Math.round(

View File

@@ -2,7 +2,6 @@ import sleep from 'await-sleep'
import got from 'got' import got from 'got'
const ONE_SECOND = 1000 const ONE_SECOND = 1000
const ONE_MINUTE = 60 * ONE_SECOND
async function purgeFastlyBySurrogateKey({ apiToken, serviceId, surrogateKey }) { async function purgeFastlyBySurrogateKey({ apiToken, serviceId, surrogateKey }) {
const key = surrogateKey const key = surrogateKey
@@ -17,17 +16,10 @@ async function purgeFastlyBySurrogateKey({ apiToken, serviceId, surrogateKey })
return got.post(requestPath, { headers, json: true }) return got.post(requestPath, { headers, json: true })
} }
// This delay (includeDelayForPreboot) can potentially be removed in the export default async function purgeEdgeCache() {
// future if the deployment workflow is updated to include a delay to offset
// Heroku Preboot before this script runs.
export default async function purgeEdgeCache({ includeDelayForPreboot = true } = {}) {
// If Heroku Preboot is enabled, then there is an additional delay of at
// least 2 minutes before the new dynos are swapped into active serving.
const delayForPrebootSwap = 2 * ONE_MINUTE + 30 * ONE_SECOND
// Give the app some extra time to wake up before the thundering herd of // Give the app some extra time to wake up before the thundering herd of
// Fastly requests. // Fastly requests.
const delayBeforeFirstPurge = ONE_MINUTE const delayBeforeFirstPurge = 30 * ONE_SECOND
// Evidence has shown that it's necessary to purge twice to ensure all // Evidence has shown that it's necessary to purge twice to ensure all
// customers see fresh content. // customers see fresh content.
@@ -47,11 +39,6 @@ export default async function purgeEdgeCache({ includeDelayForPreboot = true } =
surrogateKey: FASTLY_SURROGATE_KEY, surrogateKey: FASTLY_SURROGATE_KEY,
} }
if (includeDelayForPreboot) {
console.log('Waiting for Heroku Preboot to swap dynos...')
await sleep(delayForPrebootSwap)
}
console.log('Waiting extra time to prevent a Thundering Herd problem...') console.log('Waiting extra time to prevent a Thundering Herd problem...')
await sleep(delayBeforeFirstPurge) await sleep(delayBeforeFirstPurge)