From b866089c64b0ab50f95523bd30d3e77c593baea0 Mon Sep 17 00:00:00 2001 From: chris48s <chris48s@users.noreply.github.com> Date: Fri, 26 Oct 2018 20:08:02 +0100 Subject: [PATCH] allow badge maxAge to be set by category; affects [discord] (#2205) * allow badge maxAge to be set by category * override default cache length for [discord] * update maxAge docs --- frontend/components/usage.js | 5 +++-- lib/request-handler.js | 29 +++++++++++++++++++++-------- lib/request-handler.spec.js | 12 ++++++++++++ services/base.js | 10 ++++++++++ services/discord/discord.service.js | 4 ++++ 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/frontend/components/usage.js b/frontend/components/usage.js index 923ce7eced..a94cc4560c 100644 --- a/frontend/components/usage.js +++ b/frontend/components/usage.js @@ -269,8 +269,9 @@ export default class Usage extends React.PureComponent { <code>?maxAge=3600</code> </td> <td> - Set the HTTP cache lifetime in secs (values below the default - (currently 120 seconds) will be ignored) + Set the HTTP cache lifetime in secs (rules are applied to infer + a default value on a per-badge basis, any values specified below + the default will be ignored) </td> </tr> </tbody> diff --git a/lib/request-handler.js b/lib/request-handler.js index 48d99ed5c9..aa93684ecd 100644 --- a/lib/request-handler.js +++ b/lib/request-handler.js @@ -56,10 +56,29 @@ function flattenQueryParams(queryParams) { return Array.from(union).sort() } +function getBadgeMaxAge(handlerOptions, queryParams) { + let maxAge = isInt(process.env.BADGE_MAX_AGE_SECONDS) + ? parseInt(process.env.BADGE_MAX_AGE_SECONDS) + : 120 + if (handlerOptions.cacheLength) { + // if we've set a more specific cache length for this badge (or category), + // use that instead of env.BADGE_MAX_AGE_SECONDS + maxAge = parseInt(handlerOptions.cacheLength) + } + if (isInt(queryParams.maxAge) && parseInt(queryParams.maxAge) > maxAge) { + // only allow queryParams.maxAge to override the default + // if it is greater than the default + maxAge = parseInt(queryParams.maxAge) + } + return maxAge +} + // handlerOptions can contain: // - handler: The service's request handler function // - queryParams: An array of the field names of any custom query parameters // the service uses +// - cacheLength: An optional badge or category-specific cache length +// (in number of seconds) to be used in preference to the default // // For safety, the service must declare the query parameters it wants to use. // Only the declared parameters (and the global parameters) are provided to @@ -81,14 +100,7 @@ function handleRequest(makeBadge, handlerOptions) { return (queryParams, match, end, ask) => { const reqTime = new Date() - let maxAge = isInt(process.env.BADGE_MAX_AGE_SECONDS) - ? parseInt(process.env.BADGE_MAX_AGE_SECONDS) - : 120 - if (isInt(queryParams.maxAge) && parseInt(queryParams.maxAge) > maxAge) { - // only queryParams.maxAge to override the default - // if it is greater than env.BADGE_MAX_AGE_SECONDS - maxAge = parseInt(queryParams.maxAge) - } + const maxAge = getBadgeMaxAge(handlerOptions, queryParams) // send both Cache-Control max-age and Expires // in case the client implements HTTP/1.0 but not HTTP/1.1 if (maxAge === 0) { @@ -269,4 +281,5 @@ module.exports = { clearRequestCache, // Expose for testing. _requestCache: requestCache, + getBadgeMaxAge, } diff --git a/lib/request-handler.spec.js b/lib/request-handler.spec.js index d3fc1b4f12..1adba41078 100644 --- a/lib/request-handler.spec.js +++ b/lib/request-handler.spec.js @@ -1,6 +1,7 @@ 'use strict' const { expect } = require('chai') +const { test, given } = require('sazerac') const fetch = require('node-fetch') const config = require('./test-config') const Camp = require('camp') @@ -10,6 +11,7 @@ const { makeHandleRequestFn, clearRequestCache, _requestCache, + getBadgeMaxAge, } = require('./request-handler') const testHelpers = require('./make-badge-test-helpers') @@ -206,4 +208,14 @@ describe('The request handler', function() { }) }) }) + + describe('getBadgeMaxAge function', function() { + process.env.BADGE_MAX_AGE_SECONDS = 120 + test(getBadgeMaxAge, () => { + given({}, {}).expect(120) + given({ cacheLength: 900 }, {}).expect(900) + given({ cacheLength: 900 }, { maxAge: 1000 }).expect(1000) + given({ cacheLength: 900 }, { maxAge: 400 }).expect(900) + }) + }) }) diff --git a/services/base.js b/services/base.js index ce9a684ff4..2cf802dd3a 100644 --- a/services/base.js +++ b/services/base.js @@ -165,6 +165,15 @@ class BaseService { return new RegExp(fullRegex) } + static get _cacheLength() { + const cacheLengths = { + build: 30, + license: 3600, + version: 300, + } + return cacheLengths[this.category] + } + static _namedParamsForMatch(match) { const names = this.url.capture || [] @@ -315,6 +324,7 @@ class BaseService { const format = match.slice(-1)[0] sendBadge(format, badgeData) }, + cacheLength: this._cacheLength, }) ) } diff --git a/services/discord/discord.service.js b/services/discord/discord.service.js index 414820d86f..6b2bae01d8 100644 --- a/services/discord/discord.service.js +++ b/services/discord/discord.service.js @@ -22,6 +22,10 @@ module.exports = class Discord extends BaseJsonService { }) } + static get _cacheLength() { + return 30 + } + static render({ members }) { return { message: `${members} online`, -- GitLab