From 19133483f47f6a02a9a42c310b0a4d18cb37dbc4 Mon Sep 17 00:00:00 2001 From: Jeff Posnick Date: Wed, 20 Apr 2016 11:28:24 -0400 Subject: [PATCH] Guard against empty caches due to a previously aborted install handler --- service-worker.tmpl | 49 +++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/service-worker.tmpl b/service-worker.tmpl index 49e5d20..3600277 100644 --- a/service-worker.tmpl +++ b/service-worker.tmpl @@ -1,5 +1,5 @@ /** - * Copyright 2015 Google Inc. All rights reserved. + * Copyright 2016 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,33 +65,42 @@ self.addEventListener('install', function(event) { var now = Date.now(); event.waitUntil( - caches.keys().then(function(allCacheNames) { - return Promise.all( - Object.keys(CurrentCacheNamesToAbsoluteUrl).filter(function(cacheName) { - return allCacheNames.indexOf(cacheName) === -1; - }).map(function(cacheName) { - var urlWithCacheBusting = getCacheBustedUrl(CurrentCacheNamesToAbsoluteUrl[cacheName], - now); - - return caches.open(cacheName).then(function(cache) { - var request = new Request(urlWithCacheBusting, {credentials: 'same-origin'}); + // Take a look at each of the cache names we expect for this version. + Promise.all(Object.keys(CurrentCacheNamesToAbsoluteUrl).map(function(cacheName) { + return caches.open(cacheName).then(function(cache) { + // Get a list of all the entries in the specific named cache. + // For caches that are already populated for a given version of a + // resource, there should be 1 entry. + return cache.keys().then(function(keys) { + if (keys.length === 0) { + // If there are 0 entries, either because this is a brand new version + // of a resource or because the install step was interrupted the + // last time it ran, then we need to populate the cache. + var urlWithCacheBusting = getCacheBustedUrl( + CurrentCacheNamesToAbsoluteUrl[cacheName], now); + + var request = new Request(urlWithCacheBusting, + {credentials: 'same-origin'}); return fetch(request).then(function(response) { if (response.ok) { - return cache.put(CurrentCacheNamesToAbsoluteUrl[cacheName], response); + return cache.put(CurrentCacheNamesToAbsoluteUrl[cacheName], + response); } - console.error('Request for %s returned a response with status %d, so not attempting to cache it.', + console.error('Request for %s returned a response status %d, ' + + 'so not attempting to cache it.', urlWithCacheBusting, response.status); // Get rid of the empty cache if we can't add a successful response to it. return caches.delete(cacheName); }); - }); - }) - ).then(function() { - return Promise.all( - allCacheNames.filter(function(cacheName) { - return cacheName.indexOf(CacheNamePrefix) === 0 && - !(cacheName in CurrentCacheNamesToAbsoluteUrl); + } + }); + }); + })).then(function() { + return caches.keys().then(function(allCacheNames) { + return Promise.all(allCacheNames.filter(function(cacheName) { + return cacheName.indexOf(CacheNamePrefix) === 0 && + !(cacheName in CurrentCacheNamesToAbsoluteUrl); }).map(function(cacheName) { return caches.delete(cacheName); })