Limit activation readiness checks to blocking assets
This commit is contained in:
@@ -49,14 +49,13 @@
|
|||||||
return response ? response.json() : null;
|
return response ? response.json() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function status(manifest, cache, { previous, activeLayout } = {}) {
|
async function status(manifest, cache, { previous, activeLayout, offline = true } = {}) {
|
||||||
const found = await Promise.all(blocking(manifest, previous, activeLayout).map(async path => {
|
const found = await Promise.all(blocking(manifest, previous, activeLayout).map(async path => {
|
||||||
const response = await cache.match(url(path, manifest.files[path]));
|
const response = await cache.match(url(path, manifest.files[path]));
|
||||||
return !!response && response.headers.get('X-Asset-Hash') === manifest.files[path].h;
|
return !!response && response.headers.get('X-Asset-Hash') === manifest.files[path].h;
|
||||||
}));
|
}));
|
||||||
const missing = found.filter(value => !value).length;
|
const missing = found.filter(value => !value).length;
|
||||||
const offline = await completeness(manifest, cache);
|
return { ready: missing === 0, missing, version: manifest.buildTag, ...(offline ? await completeness(manifest, cache) : {}) };
|
||||||
return { ready: missing === 0, missing, version: manifest.buildTag, ...offline };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// All concurrent messages/layout jobs in this worker share six download slots.
|
// All concurrent messages/layout jobs in this worker share six download slots.
|
||||||
@@ -117,7 +116,7 @@
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
if (failure) throw failure;
|
if (failure) throw failure;
|
||||||
if (!groups && !all && !(await status(manifest, cache, { previous, activeLayout })).ready) throw new Error('Incomplete blocking assets');
|
if (!groups && !all && !(await status(manifest, cache, { previous, activeLayout, offline: false })).ready) throw new Error('Incomplete blocking assets');
|
||||||
return { refreshed: count, caches: 1 };
|
return { refreshed: count, caches: 1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,12 +124,12 @@
|
|||||||
// Verified cache entries are the durable progress journal. Counters are rebuilt
|
// Verified cache entries are the durable progress journal. Counters are rebuilt
|
||||||
// after worker termination or browser eviction; never trust a stored ready bit.
|
// after worker termination or browser eviction; never trust a stored ready bit.
|
||||||
async function completeness(manifest, cache) {
|
async function completeness(manifest, cache) {
|
||||||
const missingFiles = [];
|
const files = paths(manifest);
|
||||||
for (const path of paths(manifest)) {
|
const missingFiles = (await Promise.all(files.map(async path => {
|
||||||
const response = await cache.match(url(path, manifest.files[path]));
|
const response = await cache.match(url(path, manifest.files[path]));
|
||||||
if (!response || response.headers.get('X-Asset-Hash') !== manifest.files[path].h) missingFiles.push(path);
|
return !response || response.headers.get('X-Asset-Hash') !== manifest.files[path].h ? path : null;
|
||||||
}
|
}))).filter(Boolean);
|
||||||
const total = paths(manifest).length;
|
const total = files.length;
|
||||||
return { offlineReady: missingFiles.length === 0, cached: total - missingFiles.length, total, missingFiles };
|
return { offlineReady: missingFiles.length === 0, cached: total - missingFiles.length, total, missingFiles };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +166,7 @@
|
|||||||
|
|
||||||
async function commit(manifest, cache, { previousClients, activeLayout } = {}) {
|
async function commit(manifest, cache, { previousClients, activeLayout } = {}) {
|
||||||
const old = await state(cache);
|
const old = await state(cache);
|
||||||
if (!(await status(manifest, cache, { previous: old?.current, activeLayout })).ready) {
|
if (!(await status(manifest, cache, { previous: old?.current, activeLayout, offline: false })).ready) {
|
||||||
throw new Error('Incomplete blocking assets');
|
throw new Error('Incomplete blocking assets');
|
||||||
}
|
}
|
||||||
const sameBuild = old?.current?.buildTag === manifest.buildTag;
|
const sameBuild = old?.current?.buildTag === manifest.buildTag;
|
||||||
|
|||||||
@@ -81,3 +81,11 @@ test('overlapping layout and completion jobs share a six-download ceiling',async
|
|||||||
await Promise.all([core.complete(m,{cache:c,fetchFn}),core.syncAssets(m,{cache:c,fetchFn,groups:['extra']})]);
|
await Promise.all([core.complete(m,{cache:c,fetchFn}),core.syncAssets(m,{cache:c,fetchFn,groups:['extra']})]);
|
||||||
assert.ok(peak<=6);assert.ok([...calls.values()].every(count=>count===1));
|
assert.ok(peak<=6);assert.ok([...calls.values()].every(count=>count===1));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('blocking commit never waits on an optional file readiness probe',{timeout:1000},async()=>{
|
||||||
|
const c=cache(),m=manifest();m.files['/extra.js']={h:'extra'};m.groups.extra={files:['/extra.js'],background:true,contract:1};
|
||||||
|
await c.put('/a.js?v=a',response('a'));await c.put('/index.html?v=b',response('b'));
|
||||||
|
const match=c.match;let extraProbes=0;c.match=async key=>{if(key==='/extra.js?v=extra'){extraProbes++;return new Promise(()=>{});}return match(key);};
|
||||||
|
await core.commit(m,c);assert.equal(extraProbes,0);assert.equal((await core.state(c)).current.buildTag,m.buildTag);
|
||||||
|
c.match=match;assert.equal((await core.status(m,c)).offlineReady,false);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user