WIP store-agnostic cache manager.
Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Vendored
+22
@@ -68,6 +68,28 @@ export interface Config {
|
||||
connection: string | object;
|
||||
};
|
||||
|
||||
/** Cache connection configuration, select cache type using the `store` field */
|
||||
cache?:
|
||||
| {
|
||||
store: 'memory';
|
||||
}
|
||||
| {
|
||||
store: 'memcache';
|
||||
connection: {
|
||||
/**
|
||||
* An array of memcache hosts, optionally including a port number.
|
||||
* e.g. 127.0.0.1:11211
|
||||
*/
|
||||
hosts: string[];
|
||||
|
||||
/**
|
||||
* Number of milliseconds to wait before assuming there is a
|
||||
* network timeout. Defaults to 500ms.
|
||||
*/
|
||||
netTimeout?: number;
|
||||
};
|
||||
};
|
||||
|
||||
cors?: {
|
||||
origin?: string | string[];
|
||||
methods?: string | string[];
|
||||
|
||||
@@ -36,10 +36,13 @@
|
||||
"@backstage/integration": "^0.5.2",
|
||||
"@google-cloud/storage": "^5.8.0",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"@types/cache-manager": "^3.4.0",
|
||||
"@types/cors": "^2.8.6",
|
||||
"@types/dockerode": "^3.2.1",
|
||||
"@types/express": "^4.17.6",
|
||||
"archiver": "^5.0.2",
|
||||
"cache-manager": "^3.4.3",
|
||||
"cache-manager-memcached-store": "^4.0.0",
|
||||
"compression": "^1.7.4",
|
||||
"concat-stream": "^2.0.0",
|
||||
"cors": "^2.8.5",
|
||||
@@ -54,6 +57,7 @@
|
||||
"knex": "^0.95.1",
|
||||
"lodash": "^4.17.15",
|
||||
"logform": "^2.1.1",
|
||||
"memcache-pp": "^0.3.3",
|
||||
"minimatch": "^3.0.4",
|
||||
"minimist": "^1.2.5",
|
||||
"morgan": "^1.10.0",
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import cacheManager from 'cache-manager';
|
||||
// @ts-expect-error
|
||||
import Memcache from 'memcache-pp';
|
||||
// @ts-expect-error
|
||||
import memcachedStore from 'cache-manager-memcached-store';
|
||||
|
||||
/**
|
||||
* A Cache Manager, which is able to retrieve a `node-cache-manager`-compliant
|
||||
* cache client, configured according to app configuration. If no cache is
|
||||
* configured, or an unknown store is provided, a no-op cache instance will be
|
||||
* returned.
|
||||
*/
|
||||
export class CacheManager {
|
||||
private readonly storeGetterMap = {
|
||||
memcache: this.getMemcacheClient,
|
||||
memory: this.getMemoryClient,
|
||||
none: this.getNoneClient,
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new CacheManager instance by reading from the `backend` config
|
||||
* section, specifically the `.cache` key.
|
||||
*
|
||||
* @param config The loaded application configuration.
|
||||
*/
|
||||
static fromConfig(config: Config): CacheManager {
|
||||
return new CacheManager(config.getConfig('backend.cache'));
|
||||
}
|
||||
|
||||
private constructor(private readonly config: Config) {}
|
||||
|
||||
getClientWithTtl(ttl: number): cacheManager.Cache {
|
||||
const store = this.config.getOptionalString(
|
||||
'store',
|
||||
) as keyof CacheManager['storeGetterMap'];
|
||||
|
||||
if (this.storeGetterMap.hasOwnProperty(store)) {
|
||||
return this.storeGetterMap[store].call(this, ttl);
|
||||
}
|
||||
return this.storeGetterMap.none.call(this, ttl);
|
||||
}
|
||||
|
||||
private getMemcacheClient(ttl: number): cacheManager.Cache {
|
||||
const hosts = this.config.getStringArray('connection.hosts');
|
||||
const netTimeout = this.config.getOptionalNumber('connection.netTimeout');
|
||||
return cacheManager.caching({
|
||||
store: memcachedStore,
|
||||
driver: Memcache,
|
||||
options: {
|
||||
hosts,
|
||||
...(netTimeout && { netTimeout }),
|
||||
},
|
||||
ttl,
|
||||
});
|
||||
}
|
||||
|
||||
private getMemoryClient(ttl: number): cacheManager.Cache {
|
||||
return cacheManager.caching({
|
||||
store: 'memory',
|
||||
ttl,
|
||||
});
|
||||
}
|
||||
|
||||
private getNoneClient(ttl: number): cacheManager.Cache {
|
||||
return cacheManager.caching({
|
||||
store: 'none',
|
||||
ttl,
|
||||
});
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './CacheManager';
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './cache';
|
||||
export * from './config';
|
||||
export * from './database';
|
||||
export * from './discovery';
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
import Router from 'express-promise-router';
|
||||
import {
|
||||
CacheManager,
|
||||
createServiceBuilder,
|
||||
getRootLogger,
|
||||
loadBackendConfig,
|
||||
@@ -59,11 +60,12 @@ function makeCreateEnv(config: Config) {
|
||||
root.info(`Created UrlReader ${reader}`);
|
||||
|
||||
const databaseManager = SingleConnectionDatabaseManager.fromConfig(config);
|
||||
const cache = CacheManager.fromConfig(config);
|
||||
|
||||
return (plugin: string): PluginEnvironment => {
|
||||
const logger = root.child({ type: 'plugin', plugin });
|
||||
const database = databaseManager.forPlugin(plugin);
|
||||
return { logger, database, config, reader, discovery };
|
||||
return { logger, cache, database, config, reader, discovery };
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import { Logger } from 'winston';
|
||||
import { Config } from '@backstage/config';
|
||||
import {
|
||||
CacheManager,
|
||||
PluginDatabaseManager,
|
||||
PluginEndpointDiscovery,
|
||||
UrlReader,
|
||||
@@ -24,6 +25,7 @@ import {
|
||||
|
||||
export type PluginEnvironment = {
|
||||
logger: Logger;
|
||||
cache: CacheManager;
|
||||
database: PluginDatabaseManager;
|
||||
config: Config;
|
||||
reader: UrlReader;
|
||||
|
||||
@@ -5737,6 +5737,11 @@
|
||||
resolved "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz#e190a5a548e0b348adb0df9ac7fa5f1151c7cca4"
|
||||
integrity sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==
|
||||
|
||||
"@types/cache-manager@^3.4.0":
|
||||
version "3.4.0"
|
||||
resolved "https://registry.npmjs.org/@types/cache-manager/-/cache-manager-3.4.0.tgz#414136ea3807a8cd071b8f20370c5df5dbffd382"
|
||||
integrity sha512-XVbn2HS+O+Mk2SKRCjr01/8oD5p2Tv1fxxdBqJ0+Cl+UBNiz0WVY5rusHpMGx+qF6Vc2pnRwPVwSKbGaDApCpw==
|
||||
|
||||
"@types/cacheable-request@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976"
|
||||
@@ -8152,6 +8157,11 @@ async@0.9.x:
|
||||
resolved "https://registry.npmjs.org/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
|
||||
integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=
|
||||
|
||||
async@3.2.0, async@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
|
||||
integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
|
||||
|
||||
async@^2.0.1, async@^2.6.1, async@^2.6.2:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.npmjs.org/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
|
||||
@@ -8826,7 +8836,7 @@ block-stream@*:
|
||||
dependencies:
|
||||
inherits "~2.0.0"
|
||||
|
||||
bluebird@3.7.2, bluebird@^3.3.5, bluebird@^3.5.1, bluebird@^3.5.5, bluebird@^3.7.2:
|
||||
bluebird@3.7.2, bluebird@^3.3.5, bluebird@^3.4.1, bluebird@^3.5.1, bluebird@^3.5.5, bluebird@^3.7.2:
|
||||
version "3.7.2"
|
||||
resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
||||
@@ -9251,6 +9261,20 @@ cache-base@^1.0.1:
|
||||
union-value "^1.0.0"
|
||||
unset-value "^1.0.0"
|
||||
|
||||
cache-manager-memcached-store@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/cache-manager-memcached-store/-/cache-manager-memcached-store-4.0.0.tgz#f68d00cdfaa73696d13137b7b0f39397167d9220"
|
||||
integrity sha512-Lv1WMaRC1FQHHqxE8Xbi7YWInhgfxjOmLEE6u1K0A3Rwmq+XRLyekKDM7aW9WIzF+PuII/RDKqBK/Ezo5H2QVw==
|
||||
|
||||
cache-manager@^3.4.3:
|
||||
version "3.4.3"
|
||||
resolved "https://registry.npmjs.org/cache-manager/-/cache-manager-3.4.3.tgz#c978d58f82b414ade08903d4d72b56a80a4978be"
|
||||
integrity sha512-6+Hfzy1SNs/thUwo+07pV0ozgxc4sadrAN0eFVGvXl/X9nz3J0BqEnnEoyxEn8jnF+UkEo0MKpyk9BO80hMeiQ==
|
||||
dependencies:
|
||||
async "3.2.0"
|
||||
lodash "^4.17.21"
|
||||
lru-cache "6.0.0"
|
||||
|
||||
cacheable-lookup@^5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz#049fdc59dffdd4fc285e8f4f82936591bd59fec3"
|
||||
@@ -9457,6 +9481,11 @@ capture-exit@^2.0.0:
|
||||
dependencies:
|
||||
rsvp "^4.8.4"
|
||||
|
||||
carrier@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.npmjs.org/carrier/-/carrier-0.3.0.tgz#bd295d1d3a7524cac63dd779b929ee22a362bad4"
|
||||
integrity sha1-vSldHTp1JMrGPdd5uSnuIqNiutQ=
|
||||
|
||||
case-sensitive-paths-webpack-plugin@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz#23ac613cc9a856e4f88ff8bb73bbb5e989825cf7"
|
||||
@@ -10273,6 +10302,11 @@ connect-history-api-fallback@^1.6.0:
|
||||
resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
|
||||
integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
|
||||
|
||||
connection-parse@0.0.x:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.npmjs.org/connection-parse/-/connection-parse-0.0.7.tgz#18e7318aab06a699267372b10c5226d25a1c9a69"
|
||||
integrity sha1-GOcxiqsGppkmc3KxDFIm0locmmk=
|
||||
|
||||
console-browserify@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
|
||||
@@ -14746,6 +14780,14 @@ hash.js@^1.0.0, hash.js@^1.0.3:
|
||||
inherits "^2.0.3"
|
||||
minimalistic-assert "^1.0.1"
|
||||
|
||||
hashring@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/hashring/-/hashring-3.2.0.tgz#fda4efde8aa22cdb97fb1d2a65e88401e1c144ce"
|
||||
integrity sha1-/aTv3oqiLNuX+x0qZeiEAeHBRM4=
|
||||
dependencies:
|
||||
connection-parse "0.0.x"
|
||||
simple-lru-cache "0.0.x"
|
||||
|
||||
hast-util-parse-selector@^2.0.0:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.4.tgz#60c99d0b519e12ab4ed32e58f150ec3f61ed1974"
|
||||
@@ -18023,6 +18065,13 @@ lru-cache@2:
|
||||
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952"
|
||||
integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=
|
||||
|
||||
lru-cache@6.0.0, lru-cache@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
|
||||
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
lru-cache@^4.0.1:
|
||||
version "4.1.5"
|
||||
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
|
||||
@@ -18038,13 +18087,6 @@ lru-cache@^5.0.0, lru-cache@^5.1.1:
|
||||
dependencies:
|
||||
yallist "^3.0.2"
|
||||
|
||||
lru-cache@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
|
||||
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
lru-queue@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3"
|
||||
@@ -18336,6 +18378,17 @@ media-typer@0.3.0:
|
||||
resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||
|
||||
memcache-pp@^0.3.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.npmjs.org/memcache-pp/-/memcache-pp-0.3.3.tgz#3124830e27d55a252499726510841590ac130c99"
|
||||
integrity sha512-fMitetT5ulUs4DnFaoVqWHrTBiddLG/l8rMHXbV+ibuL7uWjBulaEf8koTBEweyrjmflqhbH4Uy9V709LadXSA==
|
||||
dependencies:
|
||||
bluebird "^3.4.1"
|
||||
carrier "^0.3.0"
|
||||
debug "^2.6.9"
|
||||
hashring "^3.2.0"
|
||||
immutable "^3.8.1"
|
||||
|
||||
memoize-one@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0"
|
||||
@@ -23780,6 +23833,11 @@ simple-get@^3.0.2, simple-get@^3.0.3:
|
||||
once "^1.3.1"
|
||||
simple-concat "^1.0.0"
|
||||
|
||||
simple-lru-cache@0.0.x:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.npmjs.org/simple-lru-cache/-/simple-lru-cache-0.0.2.tgz#d59cc3a193c1a5d0320f84ee732f6e4713e511dd"
|
||||
integrity sha1-1ZzDoZPBpdAyD4Tucy9uRxPlEd0=
|
||||
|
||||
simple-swizzle@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
|
||||
|
||||
Reference in New Issue
Block a user