Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wrangler] Add deploy --old-asset-ttl option #3384

Conversation

Peter-Sparksuite
Copy link
Contributor

@Peter-Sparksuite Peter-Sparksuite commented May 31, 2023

Fixes #3385

What this PR solves / how to test:

When a wrangler deploy happens, the old assets are immediately deleted, causing users of previously obtained web applications that expect to find specific resources to no longer have access to them, resulting in users seeing 404 errors rather quickly.

Wrangler 1.x attempted to address this by way of cloudflare/wrangler-legacy#2221, which caused the default behavior to be a delaying of the old asset removal, but, the cache could become large with repeated deploys causing expirations being extended repeatedly (well, that was one issue...), so it was reverted.

Even though this delayed expiration of old assets was removed in subsequent Wrangler 1.x builds, we see this as a needed behavior, and stuck with the version of Wrangler 1.x that had this delayed removal of old content.

Now, migrating to Wrangler 3.x, and finding that having delayed expiration of old assets is not available, we want to add this as a non-default optional behavior, so that those that want it can have it, while not affecting others.

This implementation also avoids the extending of existing expiration target times, which helps limit cache growth.

Test by running wrangler deploy and see that old assets are immediately removed.

Test by running wrangler deploy --old-asset-ttl 300.

The console output will show some slight differences in the Building list of assets to upload... section, in the case where assets are to be expired rather than removed.

Later, after the upload of new assets is done, the heading of Expiring [x] stale assets... (default behavior shows Removing [x] stale assets), and the new listing of each of the individual assets as they are processed. Each asset listed will either have no suffix (meaning they are newly being set an expiration), or, a suffix of (already expiring at [x]) which indicates we are not modifying their expiration and informs what the expiration target is.

Here is an example:

Fetching list of already uploaded assets...
Building list of assets to upload...
 + asset-manifest.bb06bb849a.json (uploading new version of asset-manifest.json)
 = favicon.0d8f16a2e5.ico (already uploaded favicon.ico)
 + index.a03bf1cef7.html (uploading new version of index.html)
 = logo192.354824eae7.png (already uploaded logo192.png)
 = logo512.06ae39e3db.png (already uploaded logo512.png)
 = manifest.a8a29b1c26.json (already uploaded manifest.json)
 = robots.3dc2c2b649.txt (already uploaded robots.txt)
 = static/css/main.073c9b0a.3ef794adc1.css (already uploaded static/css/main.073c9b0a.css)
 = static/css/main.073c9b0a.css.853edb5083.map (already uploaded static/css/main.073c9b0a.css.map)
 = static/js/787.28cb0dcd.chunk.e0a3d4baf0.js (already uploaded static/js/787.28cb0dcd.chunk.js)
 = static/js/787.28cb0dcd.chunk.js.7768df2e2b.map (already uploaded static/js/787.28cb0dcd.chunk.js.map)
 + static/js/main.abc72fab.19dedd345b.js (uploading new version of static/js/main.abc72fab.js)
 + static/js/main.abc72fab.js.LICENSE.755a56ab2d.txt (uploading new version of static/js/main.abc72fab.js.LICENSE.txt)
 + static/js/main.abc72fab.js.823c394a10.map (uploading new version of static/js/main.abc72fab.js.map)
 = static/media/logo.6ce24c58023cc2f8fd88fe9d219db6c6.aa1ff94b2b.svg (already uploaded static/media/logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg)
 - asset-manifest.2d6fcfc986.json (expiring as stale)
 - asset-manifest.83a7455e64.json (expiring as stale)
 - asset-manifest.f282d05f73.json (expiring as stale)
 - index.39d4ff0064.html (expiring as stale)
 - index.8c7a61abd5.html (expiring as stale)
 - index.f45e002b58.html (expiring as stale)
 - static/js/main.24df5ff3.5102bcbe6b.js (expiring as stale)
 - static/js/main.24df5ff3.js.9e4aa97270.map (expiring as stale)
 - static/js/main.24df5ff3.js.LICENSE.755a56ab2d.txt (expiring as stale)
 - static/js/main.2e94c4c7.b9d33f0ca9.js (expiring as stale)
 - static/js/main.2e94c4c7.js.5f68c68cfd.map (expiring as stale)
 - static/js/main.2e94c4c7.js.LICENSE.755a56ab2d.txt (expiring as stale)
 - static/js/main.eeb9fd6c.1d6ce605a9.js (expiring as stale)
 - static/js/main.eeb9fd6c.js.8091f2a262.map (expiring as stale)
 - static/js/main.eeb9fd6c.js.LICENSE.755a56ab2d.txt (expiring as stale)
Uploading 5 new assets...
Skipped uploading 10 existing assets.
Uploaded 100% [5 out of 5]
Expiring 15 stale assets...
 - asset-manifest.2d6fcfc986.json (already expiring at 1685554399)
 - asset-manifest.83a7455e64.json (already expiring at 1685554375)
 - asset-manifest.f282d05f73.json 
 - index.39d4ff0064.html (already expiring at 1685554400)
 - index.8c7a61abd5.html (already expiring at 1685554376)
 - index.f45e002b58.html 
 - static/js/main.24df5ff3.5102bcbe6b.js (already expiring at 1685554377)
 - static/js/main.24df5ff3.js.9e4aa97270.map (already expiring at 1685554378)
 - static/js/main.24df5ff3.js.LICENSE.755a56ab2d.txt (already expiring at 1685554379)
 - static/js/main.2e94c4c7.b9d33f0ca9.js 
 - static/js/main.2e94c4c7.js.5f68c68cfd.map 
 - static/js/main.2e94c4c7.js.LICENSE.755a56ab2d.txt 
 - static/js/main.eeb9fd6c.1d6ce605a9.js (already expiring at 1685554401)
 - static/js/main.eeb9fd6c.js.8091f2a262.map (already expiring at 1685554402)
 - static/js/main.eeb9fd6c.js.LICENSE.755a56ab2d.txt (already expiring at 1685554403)
↗️  Done syncing assets

Note: previous immediate removals did not show a list of the assets being deleted. However, when updating the expiration target, it is considered helpful to see the list, as, each asset having its expiration changed must be pulled and then pushed again with the expiration target set, and for sites having many resources, seeing this list grow over time will be helpful to be assured progress is being made.

Associated docs issue(s)/PR(s):

cloudflare/wrangler-legacy#2221 where similar was added to Wrangler 1.x

Author has included the following, where applicable:

Reviewer is to perform the following, as applicable:

  • Checked for inclusion of relevant tests
  • Checked for inclusion of a relevant changeset
  • Checked for creation of associated docs updates
  • Manually pulled down the changes and spot-tested

@changeset-bot
Copy link

changeset-bot bot commented May 31, 2023

🦋 Changeset detected

Latest commit: 2b7aa3c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
wrangler Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Jun 16, 2023

A wrangler prerelease is available for testing. You can install this latest build in your project with:

npm install --save-dev https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/5291243880/npm-package-wrangler-3384

You can reference the automatically updated head of this PR with:

npm install --save-dev https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/prs/3384/npm-package-wrangler-3384

Or you can use npx with this latest build directly:

npx https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/5291243880/npm-package-wrangler-3384 dev path/to/script.js
Additional artifacts:
npm install https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/5291243880/npm-package-cloudflare-pages-shared-3384

Note that these links will no longer work once the GitHub Actions artifact expires.

@codecov
Copy link

codecov bot commented Jun 16, 2023

Codecov Report

Merging #3384 (2b7aa3c) into main (a728876) will decrease coverage by 0.26%.
The diff coverage is 47.05%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3384      +/-   ##
==========================================
- Coverage   75.42%   75.16%   -0.26%     
==========================================
  Files         182      183       +1     
  Lines       11063    11069       +6     
  Branches     2902     2911       +9     
==========================================
- Hits         8344     8320      -24     
- Misses       2719     2749      +30     
Impacted Files Coverage Δ
packages/wrangler/src/deploy/deploy.ts 87.50% <ø> (ø)
packages/wrangler/src/deploy/index.ts 95.12% <ø> (ø)
packages/wrangler/src/dev/remote.tsx 7.69% <ø> (ø)
packages/wrangler/src/sites.ts 91.30% <47.05%> (-4.04%) ⬇️

... and 23 files with indirect coverage changes

@admah
Copy link
Contributor

admah commented Jun 16, 2023

@Peter-Sparksuite thank you for submitting the feature request and PR. This looks like good functionality to have in Wrangler. As a heads-up - with our Pages/Workers convergence work later this year this --old-asset-ttl option will eventually be removed as all assets will have a default retention time of 1 week - https://developers.cloudflare.com/pages/platform/serving-pages/#asset-retention.

Our team will review the code shortly. One thing I notice currently is that its failing on a linting error. You should be able to run npm run check:lint or npm run fix and commit the fix to get it passing.

@Peter-Sparksuite Peter-Sparksuite requested review from a team as code owners June 16, 2023 14:45
@Peter-Sparksuite
Copy link
Contributor Author

@admah ,

Thank you for progressing this!

Seems the changeset file was not quite the way the formatted preferred - it has been updated. Please approve running the checks, as I'm not seeing any issues being reported locally, currently.

@Peter-Sparksuite
Copy link
Contributor Author

Peter-Sparksuite commented Jun 16, 2023

I'm slightly confused regarding the connection being made between this and what you've indicated at https://developers.cloudflare.com/pages/platform/serving-pages/#asset-retention

Seems that the TTL/expiration you've linked to is what's going to be applied to data that's held in the cache that's near the requester. If I understand correctly, then that's fine and good.

But, this change is about setting the TTL/expiration on KV assets that are no longer part of the deployed application, and this is only able to be done after a new deployment is done. ie: it's not about how long the data lives on the data centers near the end user that are used to distribute the data, but rather, the expiration of content that's no longer part of the actively deployed application. The related KV assets could live for a very long time before they become obsolete due to a subsequent deploy happening. eg: website has no need for changes for 3 months. I don't expect you're going to be expiring assets from the application. Setting an expiration on locally cached copies of the website assets would be fine, however, and if those assets are asked for again, the content will be fetched & cached afresh, I expect.

@Peter-Sparksuite
Copy link
Contributor Author

Hey there @admah , it's been 10 days since your last comment as I write this. The formatting issue was sorted out the same day as your last comment, but it seems there's been no further activity as yet.

Any idea as to when this will actually see some further progress? It would be really helpful to know.

And: please provide some feedback regarding #3384 (comment)

Much appreciated!
Peter

@petebacondarwin
Copy link
Contributor

Hi @Peter-Sparksuite - to set your expectation, Adam has been (and is) away for a bit at the moment so that is probably why he has not responded.

@Peter-Sparksuite
Copy link
Contributor Author

Adam has been (and is) away

Thank you for the information @petebacondarwin ! Any idea when @admah will be back?

@petebacondarwin
Copy link
Contributor

petebacondarwin commented Jun 27, 2023

He should be able to continue review in July.

@admah
Copy link
Contributor

admah commented Jul 5, 2023

@Peter-Sparksuite thanks for you patience on this as I was away. I'm good with this change, and have requested an engineering review before it gets merged.

As to my comment regarding retention time, we're currently in the process of converging Pages and Workers which will involve creating a unified asset pipeline. I don't want to get into too many specifics, so I'm simply alluding to the fact that the way static assets are currently handled in Workers is being rebuilt and may not need this flag in the future.

Copy link
Contributor

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

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

OK I think that this is OK to land, given that it requires opt-in.

But we should note the reasons why asset expiration was removed from Wrangler 1 and 2 before making use of this option.

See
cloudflare/wrangler-legacy#2224 (comment)

In particular if you have a large number of assets that change often then you can hit the rate limit on the API that Wrangler is using, causing deployments to fail.

@Peter-Sparksuite
Copy link
Contributor Author

Hey there @petebacondarwin, in regards to:

In particular if you have a large number of assets that change often then you can hit the rate limit on the API that Wrangler is using, causing deployments to fail.

I'm curious whether you saw what I mentioned about this possibility in the issue related to this pull request (last paragraph):

Reading some of the other comments, it appears it is possible this might still run into issues if there are a very large number of assets, so some pacing might need to be added? I am curious as to whether others see this as a mandatory requirement or not, but perhaps some retry logic should be added, should we get a response that indicates too many requests are being made within too short a period of time.

So I'm kinda wondering what people think about this scenario arising, and whether it's OK to just fail, or whether it should have some logic that retries individual failures repeatedly until they all succeed? Or, perhaps just let it error out, and expect the publisher, using some other mechanism, to clean things up?

Perhaps, if something is suggested to address the problem, that can be addressed via a follow-up improvement, and not necessarily something that holds up this piece?

@petebacondarwin
Copy link
Contributor

So I'm kinda wondering what people think about this scenario arising, and whether it's OK to just fail, or whether it should have some logic that retries individual failures repeatedly until they all succeed? Or, perhaps just let it error out, and expect the publisher, using some other mechanism, to clean things up?

The problem is, if I remember correctly, that the rate limiter will kick in for quite a long time, like 24 hours(?).
So if that happens you end up having to wait for the next day to try again, which is not really feasible for Wrangler to do automatically.

As far as this PR is concerned, I don't think this should block it, since you have to actively opt-in to this behaviour, and if you have problems with rate-limiting, you can always choose to opt-out again.

@petebacondarwin petebacondarwin added the e2e Run e2e tests on a PR label Jul 24, 2023
@Peter-Sparksuite
Copy link
Contributor Author

Peter-Sparksuite commented Jul 25, 2023

Hey there @petebacondarwin , I see there are some additional tests (E2E related) that were enabled, some of which are failing. Is there anything there I need to be concerned about / doing anything as a result? Much appreciated! :)

@petebacondarwin
Copy link
Contributor

Ah don't worry. The e2e tests will never run on a fork because they don't get access to the necessary secrets.

@petebacondarwin petebacondarwin merged commit ccc19d5 into cloudflare:main Jul 25, 2023
0 of 8 checks passed
@github-actions github-actions bot mentioned this pull request Jul 25, 2023
lrapoport-cf pushed a commit that referenced this pull request Aug 11, 2023
* Add Wrangler deploy --old-asset-ttl option

* Add changeset

* Provide details in the format requested

* Update formatting of changeset file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
e2e Run e2e tests on a PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

🚀 Feature Request: Allow Wrangler deployments to opt-in to expiration of old assets
3 participants