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

fix(service-worker): cache opaque responses in data groups with freshness strategy #30977

Closed
wants to merge 9 commits into from

Conversation

gkalpak
Copy link
Member

@gkalpak gkalpak commented Jun 11, 2019

  • Fix caching of opaque responses in data groups with freshness strategy.
  • Clean-up/Simplify service-worker tests.

(See individual commits for details.)

Fixes #30968.

@gkalpak gkalpak added type: bug/fix action: review The PR is still awaiting reviews from at least one requested reviewer PR target: TBD area: service-worker Issues related to the @angular/service-worker package labels Jun 11, 2019
@gkalpak gkalpak requested a review from a team as a code owner June 11, 2019 16:47
@ngbot ngbot bot added this to the needsTriage milestone Jun 11, 2019
@mary-poppins
Copy link

You can preview 84d287d at https://pr30977-84d287d.ngbuilds.io/.

@mary-poppins
Copy link

You can preview d7dab23 at https://pr30977-d7dab23.ngbuilds.io/.

Copy link
Contributor

@IgorMinar IgorMinar left a comment

Choose a reason for hiding this comment

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

Left a few comments but otherwise lgtm. Thanks!

throw new Error('No body');
const body = this.getBody();
const buffer = new ArrayBuffer(body.length);
const access = new Uint8Array(buffer);
Copy link
Contributor

Choose a reason for hiding this comment

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

access is an odd name for this const

Copy link
Member Author

Choose a reason for hiding this comment

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

I didn't change this bit (just removed the surrounding if block and adjusted the indentation).
But happy to change it so something else (view sounds like a good name).

// Only cache successful responses.
if (!res.ok || (okToCacheOpaque && res.type === 'opaque')) {
if (!(res.ok || (okToCacheOpaque && res.type === 'opaque'))) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this going to cause non-200 opaque responses to be cached?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes (if okToCacheOpaque is true, which is only the case when handling a DataGroup request with freshness (i.e. network first)).

With opaque responses, one can't tell if it was successful or not (res.status is 0, thus res.ok will always be false). So, what we do is that we cache opaque responses for DataGroup requests that are configured to fetch from the network first. So, if the client is online, the SW should fetch the response from the network anyway (and not use the cache), but if the client is offline, the SW will serve the cached response. There is little risk (other than the extra memory), because the request would have failed anyway when offline.

Jasmine natively supports returning promises from spec functions for
quite some time now. We don't need special async helpers.
Previously, opaque responses where handled a little differently than
other responses from the mock server. More specifically, they were not
tracked (so no assertions could be made for them) and their
[`Body` mixin][1] methods (such as `arrayBuffer()`, `json()`, `text()`)
would throw an error due to `body` being `null`.

This commit ensures opaque responses are also captured on the mock
server and also changes `Body` mixin methods to better simulate the
[spec'd behavior][2].

(These improvements will be necessary to test caching of opaque
responses in a subsequent commit.)

[1]: https://developer.mozilla.org/en-US/docs/Web/API/Body
[2]: https://fetch.spec.whatwg.org/#concept-body-consume-body
This commit doesn't change the behavior wrt caching, but it makes it
more explicit that only non-timed-out responses are cached. In case of a
timeout, `res` would be set to a programmatically created 504
`Response`, so `cacheResponse()` (which checks for `res.ok`) would not
have cached it anyway, but this makes change makes it more explicit (and
more similar to the equivalent part in [handleFetchWithFreshness()][1]).

[1]: https://github.com/angular/angular/blob/2b4d5c754/packages/service-worker/worker/src/data.ts#L379-L388
…hness` strategy

Previously, (presummably due to a typo) the `okToCacheOpaque` argument
of `DataGroup#cacheResponse()` was essentially never taken into account
(since opaque responses have a non-200 status code and thus `res.ok` is
always false).

This commit fixes the typo, which allows opaque responses to be cached
when `okToCacheOpaque` is true (i.e. in data groups using the
`freshness` strategy).

Fixes angular#30968
At this point, the response will have been cached (or scheduled to be
cached) in other code paths, so caching it again is redundant.
@mary-poppins
Copy link

You can preview b8b61c7 at https://pr30977-b8b61c7.ngbuilds.io/.

@gkalpak gkalpak added target: major This PR is targeted for the next major release and removed PR target: TBD labels Jun 24, 2019
@gkalpak
Copy link
Member Author

gkalpak commented Jun 24, 2019

Even if this is theoretically a fix, the code never worked as intended (i.e. opaque responses were never cached), so this is a change in behavior. Therefore, I marked it for master-only. (@IgorMinar, feel free to mark for master & patch if you think that is more appropriate.)

@gkalpak gkalpak added action: merge The PR is ready for merge by the caretaker target: patch This PR is targeted for the next patch release and removed action: review The PR is still awaiting reviews from at least one requested reviewer target: major This PR is targeted for the next major release labels Jun 26, 2019
@gkalpak
Copy link
Member Author

gkalpak commented Jun 26, 2019

Changing to master & patch, 8.1.x is the new patch branch.

alxhub pushed a commit that referenced this pull request Jun 27, 2019
Jasmine natively supports returning promises from spec functions for
quite some time now. We don't need special async helpers.

PR Close #30977
alxhub pushed a commit that referenced this pull request Jun 27, 2019
alxhub pushed a commit that referenced this pull request Jun 27, 2019
Previously, opaque responses where handled a little differently than
other responses from the mock server. More specifically, they were not
tracked (so no assertions could be made for them) and their
[`Body` mixin][1] methods (such as `arrayBuffer()`, `json()`, `text()`)
would throw an error due to `body` being `null`.

This commit ensures opaque responses are also captured on the mock
server and also changes `Body` mixin methods to better simulate the
[spec'd behavior][2].

(These improvements will be necessary to test caching of opaque
responses in a subsequent commit.)

[1]: https://developer.mozilla.org/en-US/docs/Web/API/Body
[2]: https://fetch.spec.whatwg.org/#concept-body-consume-body

PR Close #30977
alxhub pushed a commit that referenced this pull request Jun 27, 2019
…0977)

This commit doesn't change the behavior wrt caching, but it makes it
more explicit that only non-timed-out responses are cached. In case of a
timeout, `res` would be set to a programmatically created 504
`Response`, so `cacheResponse()` (which checks for `res.ok`) would not
have cached it anyway, but this makes change makes it more explicit (and
more similar to the equivalent part in [handleFetchWithFreshness()][1]).

[1]: https://github.com/angular/angular/blob/2b4d5c754/packages/service-worker/worker/src/data.ts#L379-L388

PR Close #30977
alxhub pushed a commit that referenced this pull request Jun 27, 2019
…hness` strategy (#30977)

Previously, (presummably due to a typo) the `okToCacheOpaque` argument
of `DataGroup#cacheResponse()` was essentially never taken into account
(since opaque responses have a non-200 status code and thus `res.ok` is
always false).

This commit fixes the typo, which allows opaque responses to be cached
when `okToCacheOpaque` is true (i.e. in data groups using the
`freshness` strategy).

Fixes #30968

PR Close #30977
alxhub pushed a commit that referenced this pull request Jun 27, 2019
alxhub pushed a commit that referenced this pull request Jun 27, 2019
At this point, the response will have been cached (or scheduled to be
cached) in other code paths, so caching it again is redundant.

PR Close #30977
@alxhub alxhub closed this in b6e8d19 Jun 27, 2019
alxhub pushed a commit that referenced this pull request Jun 27, 2019
alxhub pushed a commit that referenced this pull request Jun 27, 2019
Previously, opaque responses where handled a little differently than
other responses from the mock server. More specifically, they were not
tracked (so no assertions could be made for them) and their
[`Body` mixin][1] methods (such as `arrayBuffer()`, `json()`, `text()`)
would throw an error due to `body` being `null`.

This commit ensures opaque responses are also captured on the mock
server and also changes `Body` mixin methods to better simulate the
[spec'd behavior][2].

(These improvements will be necessary to test caching of opaque
responses in a subsequent commit.)

[1]: https://developer.mozilla.org/en-US/docs/Web/API/Body
[2]: https://fetch.spec.whatwg.org/#concept-body-consume-body

PR Close #30977
alxhub pushed a commit that referenced this pull request Jun 27, 2019
…0977)

This commit doesn't change the behavior wrt caching, but it makes it
more explicit that only non-timed-out responses are cached. In case of a
timeout, `res` would be set to a programmatically created 504
`Response`, so `cacheResponse()` (which checks for `res.ok`) would not
have cached it anyway, but this makes change makes it more explicit (and
more similar to the equivalent part in [handleFetchWithFreshness()][1]).

[1]: https://github.com/angular/angular/blob/2b4d5c754/packages/service-worker/worker/src/data.ts#L379-L388

PR Close #30977
alxhub pushed a commit that referenced this pull request Jun 27, 2019
…hness` strategy (#30977)

Previously, (presummably due to a typo) the `okToCacheOpaque` argument
of `DataGroup#cacheResponse()` was essentially never taken into account
(since opaque responses have a non-200 status code and thus `res.ok` is
always false).

This commit fixes the typo, which allows opaque responses to be cached
when `okToCacheOpaque` is true (i.e. in data groups using the
`freshness` strategy).

Fixes #30968

PR Close #30977
alxhub pushed a commit that referenced this pull request Jun 27, 2019
alxhub pushed a commit that referenced this pull request Jun 27, 2019
At this point, the response will have been cached (or scheduled to be
cached) in other code paths, so caching it again is redundant.

PR Close #30977
@gkalpak gkalpak deleted the fix-sw-caching-opaque branch June 27, 2019 18:30
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: service-worker Issues related to the @angular/service-worker package cla: yes target: patch This PR is targeted for the next patch release type: bug/fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support caching opaque responses with freshness strategy in ngsw-config.json [PWA][SW]
4 participants