Be able to synchronize the TTL of cache-control header to expire in a coherent way
This commit is contained in:
parent
f8e117a7b7
commit
5a7ffcf499
@ -1,14 +1,35 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;
|
const ONE_MINUTE_IN_SECONDS = 60;
|
||||||
const FIVE_MINUTES_IN_SECONDS = 60 * 5;
|
const THREE_MINUTE_IN_SECONDS = 60 * 3;
|
||||||
|
const FIVE_MINUTES_IN_SECONDS = ONE_MINUTE_IN_SECONDS * 5;
|
||||||
|
const TEN_MINUTES_IN_SECONDS = ONE_MINUTE_IN_SECONDS * 10;
|
||||||
|
const FIFTEEN_MINUTES_IN_SECONDS = ONE_MINUTE_IN_SECONDS * 15;
|
||||||
|
const THIRTY_MINUTES_IN_SECONDS = ONE_MINUTE_IN_SECONDS * 30;
|
||||||
|
const ONE_HOUR_IN_SECONDS = ONE_MINUTE_IN_SECONDS * 60;
|
||||||
|
const ONE_YEAR_IN_SECONDS = ONE_HOUR_IN_SECONDS * 24 * 365;
|
||||||
|
|
||||||
const FALLBACK_TTL = global.environment.varnish.fallbackTtl || FIVE_MINUTES_IN_SECONDS;
|
const FALLBACK_TTL = global.environment.varnish.fallbackTtl || FIVE_MINUTES_IN_SECONDS;
|
||||||
|
|
||||||
|
const validFallbackTTL = [
|
||||||
|
ONE_MINUTE_IN_SECONDS,
|
||||||
|
THREE_MINUTE_IN_SECONDS,
|
||||||
|
FIVE_MINUTES_IN_SECONDS,
|
||||||
|
TEN_MINUTES_IN_SECONDS,
|
||||||
|
FIFTEEN_MINUTES_IN_SECONDS,
|
||||||
|
THIRTY_MINUTES_IN_SECONDS,
|
||||||
|
ONE_HOUR_IN_SECONDS
|
||||||
|
];
|
||||||
|
|
||||||
module.exports = function setCacheControlHeader ({
|
module.exports = function setCacheControlHeader ({
|
||||||
ttl = ONE_YEAR_IN_SECONDS,
|
ttl = ONE_YEAR_IN_SECONDS,
|
||||||
fallbackTtl = FALLBACK_TTL,
|
fallbackTtl = FALLBACK_TTL,
|
||||||
revalidate = false
|
revalidate = false
|
||||||
} = {}) {
|
} = {}) {
|
||||||
|
if (!validFallbackTTL.includes(fallbackTtl)) {
|
||||||
|
throw new Error(`Invalid fallback TTL value for Cache-Control header. Got ${fallbackTtl}, expected ${validFallbackTTL.join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
return function setCacheControlHeaderMiddleware (req, res, next) {
|
return function setCacheControlHeaderMiddleware (req, res, next) {
|
||||||
if (req.method !== 'GET') {
|
if (req.method !== 'GET') {
|
||||||
return next();
|
return next();
|
||||||
@ -27,7 +48,7 @@ module.exports = function setCacheControlHeader ({
|
|||||||
if (everyAffectedTableCanBeInvalidated(affectedTables)) {
|
if (everyAffectedTableCanBeInvalidated(affectedTables)) {
|
||||||
directives.push(`max-age=${ttl}`);
|
directives.push(`max-age=${ttl}`);
|
||||||
} else {
|
} else {
|
||||||
directives.push(`max-age=${fallbackTtl}`);
|
directives.push(`max-age=${computeNextTTL({ ttlInSeconds: fallbackTtl })}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (revalidate) {
|
if (revalidate) {
|
||||||
@ -49,3 +70,11 @@ function everyAffectedTableCanBeInvalidated (affectedTables) {
|
|||||||
affectedTables.getTables(skipNotUpdatedAtTables, skipAnalysisCachedTables)
|
affectedTables.getTables(skipNotUpdatedAtTables, skipAnalysisCachedTables)
|
||||||
.every(table => table.updated_at !== null);
|
.every(table => table.updated_at !== null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function computeNextTTL ({ ttlInSeconds } = {}) {
|
||||||
|
const nowInSeconds = Math.ceil(Date.now() / 1000);
|
||||||
|
const secondsAfterPreviousTTLStep = nowInSeconds % ttlInSeconds;
|
||||||
|
const secondsToReachTheNextTTLStep = ttlInSeconds - secondsAfterPreviousTTLStep;
|
||||||
|
|
||||||
|
return secondsToReachTheNextTTLStep;
|
||||||
|
}
|
||||||
|
@ -79,7 +79,12 @@ describe('cache-control header', function () {
|
|||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.equal(res.headers['cache-control'], `public,max-age=${ttl}`);
|
const cacheControl = res.headers['cache-control'];
|
||||||
|
const [ type, maxAge ] = cacheControl.split(',');
|
||||||
|
const [ key, value ] = maxAge.split('=');
|
||||||
|
|
||||||
|
assert.ok(Number(value) <= ttl);
|
||||||
|
|
||||||
testClient.drain(done);
|
testClient.drain(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -114,7 +119,12 @@ describe('cache-control header', function () {
|
|||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.equal(res.headers['cache-control'], `public,max-age=${ttl}`);
|
const cacheControl = res.headers['cache-control'];
|
||||||
|
const [ type, maxAge ] = cacheControl.split(',');
|
||||||
|
const [ key, value ] = maxAge.split('=');
|
||||||
|
|
||||||
|
assert.ok(Number(value) <= ttl);
|
||||||
|
|
||||||
testClient.drain(done);
|
testClient.drain(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user