Skip to content

Commit 35e7565

Browse files
authored
feat: HTTP Cache API (#1051)
1 parent 629164a commit 35e7565

File tree

784 files changed

+6987
-28321
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

784 files changed

+6987
-28321
lines changed

.github/workflows/main.yml

+23-15
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
if: github.ref != 'refs/heads/main'
2222
runs-on: ubuntu-latest
2323
steps:
24-
- uses: actions/checkout@v3
24+
- uses: actions/checkout@v4
2525
- uses: actions/setup-node@v3
2626
with:
2727
node-version: 'lts/*'
@@ -32,7 +32,7 @@ jobs:
3232
if: github.ref != 'refs/heads/main'
3333
runs-on: ubuntu-latest
3434
steps:
35-
- uses: actions/checkout@v3
35+
- uses: actions/checkout@v4
3636
- uses: actions/setup-node@v3
3737
with:
3838
node-version: 'lts/*'
@@ -68,7 +68,7 @@ jobs:
6868
SHELLCHECK_VERSION: v0.8.0
6969
runs-on: ubuntu-latest
7070
steps:
71-
- uses: actions/checkout@v3
71+
- uses: actions/checkout@v4
7272
- uses: actions/cache@v3
7373
id: cache-shellcheck
7474
with:
@@ -98,7 +98,7 @@ jobs:
9898
if: github.ref != 'refs/heads/main'
9999
runs-on: ubuntu-latest
100100
steps:
101-
- uses: actions/checkout@v3
101+
- uses: actions/checkout@v4
102102
- name: "Install wasi-sdk-20 (linux)"
103103
run: |
104104
set -x
@@ -133,7 +133,7 @@ jobs:
133133
node-version: 18
134134
runs-on: ${{ matrix.os }}
135135
steps:
136-
- uses: actions/checkout@v3
136+
- uses: actions/checkout@v4
137137
- uses: actions/setup-node@v3
138138
with:
139139
node-version: ${{ matrix.node-version }}
@@ -161,7 +161,7 @@ jobs:
161161
needs: [ensure-cargo-installs]
162162
runs-on: ubuntu-latest
163163
steps:
164-
- uses: actions/checkout@v3
164+
- uses: actions/checkout@v4
165165
with:
166166
submodules: true
167167
- name: Install Rust 1.77.1
@@ -190,7 +190,7 @@ jobs:
190190
matrix:
191191
profile: [release, weval]
192192
steps:
193-
- uses: actions/checkout@v3
193+
- uses: actions/checkout@v4
194194
with:
195195
submodules: true
196196
- name: Install Rust 1.77.1
@@ -226,7 +226,7 @@ jobs:
226226
needs: [build-debug, ensure-cargo-installs]
227227
runs-on: ubuntu-latest
228228
steps:
229-
- uses: actions/checkout@v3
229+
- uses: actions/checkout@v4
230230
with:
231231
submodules: true
232232
- uses: actions/setup-node@v3
@@ -274,7 +274,7 @@ jobs:
274274
needs: [build, ensure-cargo-installs]
275275
runs-on: ubuntu-latest
276276
steps:
277-
- uses: actions/checkout@v3
277+
- uses: actions/checkout@v4
278278
with:
279279
submodules: true
280280
- uses: actions/setup-node@v3
@@ -329,10 +329,14 @@ jobs:
329329
matrix:
330330
platform: [viceroy, compute]
331331
profile: [release, weval]
332+
features: [none, http-cache]
333+
exclude:
334+
- platform: viceroy
335+
features: http-cache
332336
needs: [build, ensure-cargo-installs]
333337
steps:
334338
- name: Checkout fastly/js-compute-runtime
335-
uses: actions/checkout@v3
339+
uses: actions/checkout@v4
336340
with:
337341
submodules: false
338342
ref: ${{ github.head_ref || github.ref_name }}
@@ -375,12 +379,12 @@ jobs:
375379
run: npm install && cd ./integration-tests/js-compute && npm install
376380

377381
- name: Run Tests
378-
run: SUFFIX_STRING=${{matrix.profile}} node integration-tests/js-compute/test.js ${{ matrix.platform == 'viceroy' && '--local' || '' }} ${{ matrix.profile == 'weval' && '--aot' || '' }}
382+
run: SUFFIX_STRING=${{matrix.profile}} node integration-tests/js-compute/test.js --ci --skip-teardown${{ matrix.platform == 'viceroy' && ' --local' || '' }}${{ matrix.profile == 'weval' && ' --aot' || '' }}${{ matrix.features == 'http-cache' && ' --http-cache' || '' }}
379383
env:
380384
FASTLY_API_TOKEN: ${{ secrets.FASTLY_API_TOKEN }}
381385

382386
- name: Run Module Mode Tests
383-
run: SUFFIX_STRING=${{matrix.profile}} node integration-tests/js-compute/test.js --module-mode ${{ matrix.platform == 'viceroy' && '--local' || '' }} ${{ matrix.profile == 'weval' && '--aot' || '' }}
387+
run: SUFFIX_STRING=${{matrix.profile}} node integration-tests/js-compute/test.js --ci --skip-setup --module-mode${{ matrix.platform == 'viceroy' && ' --local' || '' }}${{ matrix.profile == 'weval' && ' --aot' || '' }}${{ matrix.features == 'http-cache' && ' --http-cache' || '' }}
384388
env:
385389
FASTLY_API_TOKEN: ${{ secrets.FASTLY_API_TOKEN }}
386390

@@ -393,10 +397,14 @@ jobs:
393397
fail-fast: false
394398
matrix:
395399
platform: [viceroy, compute]
400+
features: [none, http-cache]
401+
exclude:
402+
- platform: viceroy
403+
features: http-cache
396404
needs: [build-debug, ensure-cargo-installs]
397405
steps:
398406
- name: Checkout fastly/js-compute-runtime
399-
uses: actions/checkout@v3
407+
uses: actions/checkout@v4
400408
with:
401409
submodules: false
402410
ref: ${{ github.head_ref || github.ref_name }}
@@ -438,11 +446,11 @@ jobs:
438446
run: npm install && cd ./integration-tests/js-compute && npm install
439447

440448
- name: Run Tests
441-
run: SUFFIX_STRING=debug node integration-tests/js-compute/test.js --debug-build ${{ matrix.platform == 'viceroy' && '--local' || '' }}
449+
run: SUFFIX_STRING=debug node integration-tests/js-compute/test.js --ci --skip-teardown --debug-build${{ matrix.platform == 'viceroy' && ' --local' || '' }}${{ matrix.features == 'http-cache' && ' --http-cache' || '' }}
442450
env:
443451
FASTLY_API_TOKEN: ${{ secrets.FASTLY_API_TOKEN }}
444452

445453
- name: Run Module Mode Tests
446-
run: SUFFIX_STRING=debug node integration-tests/js-compute/test.js --module-mode --debug-build ${{ matrix.platform == 'viceroy' && '--local' || '' }}
454+
run: SUFFIX_STRING=debug node integration-tests/js-compute/test.js --ci --skip-setup --module-mode --debug-build${{ matrix.platform == 'viceroy' && ' --local' || '' }}${{ matrix.features == 'http-cache' && ' --http-cache' || '' }}
447455
env:
448456
FASTLY_API_TOKEN: ${{ secrets.FASTLY_API_TOKEN }}

DEVELOPMENT.md

+58-11
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ To build from source, you need to have the following tools installed to successf
5151
```
5252

5353
Build the runtime using npm:
54+
5455
```sh
5556
npm run build
5657
```
@@ -79,7 +80,7 @@ npm run build
7980
- Python
8081
```sh
8182
brew install python@3
82-
```
83+
```
8384
- Rust
8485
```sh
8586
curl -so rust.sh https://sh.rustup.rs && sh rust.sh -y
@@ -104,49 +105,95 @@ npm run build
104105
```
105106

106107
Build the runtime using npm:
108+
107109
```sh
108110
npm run build
109111
```
110112

111113
## Testing a Local build in a Compute application
112-
:warning: **You should not use this for production workloads!!!!!!!!**
114+
115+
:warning: **You should not use this for production workloads!!!!!!!!**
113116

114117
You can test a local build of the JS Compute runtime by installing it in your JavaScript Compute application and running that locally or by uploading it to your Fastly service.
115118

116119
1. First, follow the directions in [Building the JS Compute Runtime](#building-the-js-compute-runtime) for your platform to obtain a local build. The build outputs are the following files:
120+
117121
- `fastly.wasm`
118122
- `fastly.debug.wasm`
119123
- `fastly-weval.wasm`
120124
- `fastly-ics.wevalcache`
121125

122126
2. Create a local tarball using npm.
127+
123128
```shell
124129
npm pack
125130
```
126131

127132
The resulting tarball will have a filename such as `fastly-js-compute-<version>.tgz`.
128133

129134
3. In your Compute application, install the tarball using `npm`:
135+
130136
```shell
131137
npm install /path/to/fastly-js-compute-<version>.tgz
132138
```
133139

134140
4. Build and test or deploy your application as usual, using `fastly compute serve` or `fastly compute publish`, or an appropriate npm script.
135141

136142
## Testing a Dev Release in a Compute application
137-
:warning: **You should not use this for production workloads!!!!!!!!**
143+
144+
:warning: **You should not use this for production workloads!!!!!!!!**
138145

139146
Dev builds are released before production releases to allow for further testing. These are not released upstream to NPM, however you can acquire them from the [Releases](https://github.com/fastly/js-compute-runtime/releases/) section. Download the runtime for your platform, extract the executable and place it in the /node_modules/@fastly/js-compute/bin/PLATFORM folder of your Fastly Compute project. Then you can use the normal [Fastly CLI](https://github.com/fastly/cli) to build your service.
140147

141148
Please submit an [issue](https://github.com/fastly/js-compute-runtime/issues) if you find any problems during testing.
142149

143-
## Automated Testing
150+
## Tests
151+
152+
All tests are automatically run on pull requests via CI.
153+
154+
### Unit Testing
155+
156+
Unit tests are run via `npm run test`, currently including:
157+
158+
- CLI tests (`npm run test:cli`)
159+
- Typing tests (`npm run test:types`)
160+
161+
### Integration Tests
162+
163+
Complete test applications are tested from the `./integration-tests/js-compute/fixtures/app/src` and `./integration-tests/js-compute/fixtures/module-mode/src` directories.
164+
165+
Tests themselves are listed in the `./integration-tests/js-compute/fixtures/app/tests.json` and `./integration-tests/js-compute/fixtures/module-mode/tests.json` files.
166+
167+
Integration tests can be run via `npm run test:integration`, which defaults to the release build.
168+
169+
In addition the following flags can be added after the command (passed via `npm run test:debug -- ...` after the `--`):
170+
171+
- `--local`: Test locally using Viceroy, instead of publishing to a staging Compute service.
172+
- `--bail`: Immediately stop testing on the first failure, and report the failure.
173+
- `--verbose`: Adds verbose logging to `fastly compute publish` and Viceroy (which provides hostcall logging as well).
174+
- `--debug-build`: Use the debug build
175+
- `--debug-log`: Enable debug logging for the tests (engine-level DEBUG_LOG)
176+
- `--module-mode`: Run the module mode test suite (`fixtures/module-mode` instead of `fixtures/app`).
177+
- `--http-cache`: Run the HTTP cache test suite
178+
- `[...args]`: Additional arguments allow for filtering tests
179+
180+
A typical development test command is therefore something like:
181+
182+
```
183+
npm run build:debug && npm run test:integration -- --debug-build --debug-log --local --bail /crypto
184+
```
185+
186+
Which would run a debug build, enable debugging logging, and then that build against all the crypto tests locally on Viceroy, throwing an error as soon as one is found.
187+
188+
Some tests can only be run on Compute and not Viceroy and will be automatically skipped. A green tick is always shown for a test that ran successfully - if it is missing that means it did not run.
189+
190+
### Web Platform Tests
191+
192+
The Web Platform tests are included as a submodule, and can be run via `npm run test:wpt` or `npm run test:wpt:debug`.
193+
194+
The WPT test runner supports the following options (passed via `npm run test:wpt -- ...` after the `--`):
144195

145-
The JS Compute Runtime has automated tests which run on all pull-requests. The test applications are located within <./integration-tests/js-compute>.
196+
- `--update-expectations`: Update the WPT test expectations JSON files based on the current PASS/FAIL test statuses, instead of throwing an error when the current PASS/FAIL lists are not matched.
197+
- `[...args]`: Filter to apply to WPT tests to run
146198

147-
To run an end-to-end test which builds and deploys an application to fastly:
148-
- Build the runtime and cli: `npm run build` in the root of the project
149-
- Change to the test directory for the runtime: `cd integration-tests/js-compute/`
150-
- Install the test dependencies: `npm install`
151-
- Get a list of all the applications to test: `node test.js`
152-
- Test a single application via: `node test.js <name>` or test all via `node test.js --all`
199+
Run `./tests/wpt-harness/run-wpt.mjs --help` for further options information.

documentation/docs/cache-override/CacheOverride/CacheOverride.mdx

+23
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ but `CacheOverride` can be set on a [`Request`](../../globals/Request/Request.md
1818
```js
1919
new CacheOverride(mode)
2020
new CacheOverride(mode, init)
21+
new CacheOverride(init)
2122
```
2223

2324
> **Note:** `CacheOverride()` can only be constructed with `new`. Attempting to call it without `new` throws a [`TypeError`](../../globals/TypeError/TypeError.mdx).
@@ -30,6 +31,7 @@ new CacheOverride(mode, init)
3031
- `"none"`: Do not override the behavior specified in the origin response’s cache control headers.
3132
- `"pass"`: Do not cache the response to this request, regardless of the origin response’s headers.
3233
- `"override"`: Override particular cache control settings using the `CacheOverride` object's settings.
34+
This options is also the default when providing an init object directly as the first argument.
3335

3436
- `init`
3537

@@ -48,6 +50,27 @@ new CacheOverride(mode, init)
4850

4951
- `ttl` _: number_ _**optional**_
5052
- Override the caching behavior of this request to use the given Time to Live (TTL), in seconds.
53+
54+
- `beforeSend` _:Function_ _**optional**_
55+
- `(request: Request) => void | PromiseLike<void>`
56+
- Callback to be invoked if a request is going all the way to a backend, allowing the request to be modified beforehand.
57+
- See [Modifying a request as it is forwarded to a backend](https://www.fastly.com/documentation/guides/concepts/edge-state/cache/#modifying-a-request-as-it-is-forwarded-to-a-backend) in the Fastly cache interfaces documentation for details.
58+
59+
- `afterSend` _: Function_ _**optional**_
60+
- `(response: Response) => void | CacheOptions | PromiseLike<void | CacheOptions>`
61+
- Callback to be invoked after a response has been sent, but before it is stored into the cache.
62+
- Where `CacheOptions` contains:
63+
- `cache` _: boolean | 'uncacheable'_ _**optional**_
64+
- Whether to cache this response. By default, leaving this field empty, responses will be cached based on their cache header information.
65+
- Setting this to true or false will override this default cache behaviour, setting in the cache or not setting in the cache, even if the default behaviour would have been otherwise.
66+
- Setting to 'uncacheable' the response will not only not be cached, but the cache will record that the originating request led to an uncacheable response, so that future cache lookups will result in immediately going to the backend, rather than attempting to coordinate concurrent requests to reduce backend traffic.
67+
- See the [Fastly request collapsing guide](https://www.fastly.com/documentation/guides/concepts/edge-state/cache/request-collapsing/) for more details on the mechanism that `uncacheable` disables.
68+
- `bodyTransformFn` _: Function_ _**optional**_
69+
- `(body: Uint8Array) => Uint8Array | PromiseLike<Uint8Array>`
70+
- Provide a function to be used for transforming the response body prior to caching.
71+
- Body transformations are performed by specifying a transform, rather than by directly working with the body during the onAfterSend callback function, because not every response contains a fresh body: 304 Not Modified responses, which are used to revalidate a stale cached response, are valuable precisely because they do not retransmit the body.
72+
- For any other response status, the backend response will contain a relevant body, and the `bodyTransformFn` will be applied to it. The original backend body is passed in to the transform function, and the function is expected to return the new body.
73+
- See [Controlling cache behavior based on backend response](https://www.fastly.com/documentation/guides/concepts/edge-state/cache/#controlling-cache-behavior-based-on-backend-response) in the Fastly cache interfaces documentation for details.
5174

5275
### Return value
5376

documentation/docs/globals/Request/Request.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ new Request(input, options)
3939
- `body`
4040
- : Any body that you want to add to your request: this can be an `ArrayBuffer`, a `TypedArray`, a `DataView`, a `URLSearchParams`, string object or literal, or a `ReadableStream` object.
4141
- `backend` _**Fastly-specific**_
42-
- `cacheOverride` _**Fastly-specific**_
42+
- `cacheOverride` _**Fastly-specific**_, see [`CacheOverride`](../../cache-override/CacheOverride/CacheOverride.mdx).
4343
- `cacheKey` _**Fastly-specific**_
4444
- `manualFramingHeaders`_: boolean_ _**optional**_ _**Fastly-specific**_
4545
- : The default value is `false`, which means that the framing headers are automatically created based on the message body.

0 commit comments

Comments
 (0)