Chore: renames cache (#110877)
This commit is contained in:
@@ -7,7 +7,7 @@ import { Settings } from 'app/core/config';
|
||||
import { importPanelPlugin } from 'app/features/plugins/importPanelPlugin';
|
||||
import { StoreState, ThunkResult } from 'app/types/store';
|
||||
|
||||
import { invalidatePluginInCache } from '../../loader/cache';
|
||||
import { clearPluginInfoInCache } from '../../loader/pluginInfoCache';
|
||||
import {
|
||||
getRemotePlugins,
|
||||
getPluginErrors,
|
||||
@@ -206,7 +206,7 @@ export const install = createAsyncThunk<
|
||||
await updatePanels();
|
||||
|
||||
if (installType !== PluginStatus.INSTALL) {
|
||||
invalidatePluginInCache(id);
|
||||
clearPluginInfoInCache(id);
|
||||
}
|
||||
|
||||
return { id, changes };
|
||||
@@ -231,7 +231,7 @@ export const uninstall = createAsyncThunk<Update<CatalogPlugin, string>, string>
|
||||
await uninstallPlugin(id);
|
||||
await updatePanels();
|
||||
|
||||
invalidatePluginInCache(id);
|
||||
clearPluginInfoInCache(id);
|
||||
|
||||
return {
|
||||
id,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { getResolvedLanguage } from '@grafana/i18n/internal';
|
||||
import { config } from '@grafana/runtime';
|
||||
|
||||
import builtInPlugins from '../built_in_plugins';
|
||||
import { registerPluginInCache } from '../loader/cache';
|
||||
import { registerPluginInfoInCache } from '../loader/pluginInfoCache';
|
||||
import { SystemJS } from '../loader/systemjs';
|
||||
import { resolveModulePath } from '../loader/utils';
|
||||
import { importPluginModuleInSandbox } from '../sandbox/sandboxPluginLoader';
|
||||
@@ -22,7 +22,7 @@ export async function importPluginModule({
|
||||
translations,
|
||||
}: PluginImportInfo): Promise<System.Module> {
|
||||
if (version) {
|
||||
registerPluginInCache({ path, version, loadingStrategy });
|
||||
registerPluginInfoInCache({ path, version, loadingStrategy });
|
||||
}
|
||||
|
||||
// Add locales to i18n for a plugin if the feature toggle is enabled and the plugin has locales
|
||||
|
||||
@@ -2,3 +2,5 @@ export const SHARED_DEPENDENCY_PREFIX = 'package';
|
||||
export const LOAD_PLUGIN_CSS_REGEX = /^plugins.+\.css$/i;
|
||||
export const JS_CONTENT_TYPE_REGEX = /^(text|application)\/(x-)?javascript(;|$)/;
|
||||
export const CACHE_INITIALISED_AT = Date.now();
|
||||
export const PLUGIN_PATH_REGEX = /\/?public\/plugins\/([^\/]+)\//;
|
||||
export const DECOUPLED_PLUGIN_REGEX = /\/?public\/app\/plugins\/(?:datasource|panel)\/([^\/]+)\//;
|
||||
|
||||
+32
-31
@@ -1,60 +1,61 @@
|
||||
import { PluginLoadingStrategy } from '@grafana/data';
|
||||
|
||||
import {
|
||||
registerPluginInCache,
|
||||
invalidatePluginInCache,
|
||||
resolveWithCache,
|
||||
getPluginFromCache,
|
||||
registerPluginInfoInCache,
|
||||
clearPluginInfoInCache,
|
||||
resolvePluginUrlWithCache,
|
||||
getPluginInfoFromCache,
|
||||
extractCacheKeyFromPath,
|
||||
} from './cache';
|
||||
} from './pluginInfoCache';
|
||||
|
||||
jest.mock('./constants', () => ({
|
||||
...jest.requireActual('./constants'),
|
||||
CACHE_INITIALISED_AT: 123456,
|
||||
}));
|
||||
|
||||
describe('Cache Functions', () => {
|
||||
describe('registerPluginInCache', () => {
|
||||
it('should register a plugin in the cache', () => {
|
||||
describe('registerPluginInfoInCache', () => {
|
||||
it('should register pluginInfo in the cache', () => {
|
||||
const plugin = { version: '1.0.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache({ path: 'public/plugins/plugin1/module.js', ...plugin });
|
||||
expect(getPluginFromCache('plugin1')).toEqual(plugin);
|
||||
registerPluginInfoInCache({ path: 'public/plugins/plugin1/module.js', ...plugin });
|
||||
expect(getPluginInfoFromCache('plugin1')).toEqual(plugin);
|
||||
});
|
||||
|
||||
it('should not register a plugin if it already exists in the cache', () => {
|
||||
it('should not register pluginInfo if it already exists in the cache', () => {
|
||||
const path = 'public/plugins/plugin2/module.js';
|
||||
const plugin = { path, version: '2.0.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache(plugin);
|
||||
registerPluginInfoInCache(plugin);
|
||||
const plugin2 = { path, version: '2.5.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache(plugin2);
|
||||
expect(getPluginFromCache(path)?.version).toBe('2.0.0');
|
||||
registerPluginInfoInCache(plugin2);
|
||||
expect(getPluginInfoFromCache(path)?.version).toBe('2.0.0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('invalidatePluginInCache', () => {
|
||||
it('should invalidate a plugin in the cache', () => {
|
||||
describe('clearPluginInfoInCache', () => {
|
||||
it('should clear pluginInfo in the cache', () => {
|
||||
const path = 'public/plugins/plugin2/module.js';
|
||||
const plugin = { path, version: '3.0.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache(plugin);
|
||||
invalidatePluginInCache('plugin2');
|
||||
expect(getPluginFromCache('plugin2')).toBeUndefined();
|
||||
registerPluginInfoInCache(plugin);
|
||||
clearPluginInfoInCache('plugin2');
|
||||
expect(getPluginInfoFromCache('plugin2')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not throw an error if the plugin does not exist in the cache', () => {
|
||||
expect(() => invalidatePluginInCache('nonExistentPlugin')).not.toThrow();
|
||||
it('should not throw an error if the pluginInfo does not exist in the cache', () => {
|
||||
expect(() => clearPluginInfoInCache('nonExistentPlugin')).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveWithCache', () => {
|
||||
it('should resolve URL with timestamp cache bust parameter if plugin is not available in the cache', () => {
|
||||
describe('resolvePluginUrlWithCache', () => {
|
||||
it('should resolve URL with timestamp cache bust parameter if pluginInfo is not available in the cache', () => {
|
||||
const url = 'http://localhost:3000/public/plugins/plugin4/module.js';
|
||||
expect(resolveWithCache(url)).toContain('_cache=123456');
|
||||
expect(resolvePluginUrlWithCache(url)).toContain('_cache=123456');
|
||||
});
|
||||
|
||||
it('should resolve URL with plugin version as cache bust parameter if available', () => {
|
||||
const url = 'http://localhost:3000/public/plugins/plugin5/module.js';
|
||||
const plugin = { path: url, version: '5.0.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache(plugin);
|
||||
expect(resolveWithCache(url)).toContain('_cache=5.0.0');
|
||||
registerPluginInfoInCache(plugin);
|
||||
expect(resolvePluginUrlWithCache(url)).toContain('_cache=5.0.0');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -84,15 +85,15 @@ describe('Cache Functions', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPluginFromCache', () => {
|
||||
it('should return plugin from cache if exists', () => {
|
||||
describe('getPluginInfoFromCache', () => {
|
||||
it('should return pluginInfo from cache if exists', () => {
|
||||
const plugin = { version: '6.0.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache({ path: 'public/plugins/plugin6/module.js', ...plugin });
|
||||
expect(getPluginFromCache('plugin6')).toEqual(plugin);
|
||||
registerPluginInfoInCache({ path: 'public/plugins/plugin6/module.js', ...plugin });
|
||||
expect(getPluginInfoFromCache('plugin6')).toEqual(plugin);
|
||||
});
|
||||
|
||||
it('should return undefined if plugin does not exist in cache', () => {
|
||||
expect(getPluginFromCache('nonExistentPlugin')).toBeUndefined();
|
||||
it('should return undefined if pluginInfo does not exist in cache', () => {
|
||||
expect(getPluginInfoFromCache('nonExistentPlugin')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
+13
-15
@@ -2,19 +2,19 @@ import { PluginLoadingStrategy } from '@grafana/data';
|
||||
|
||||
import { clearPluginSettingsCache } from '../pluginSettings';
|
||||
|
||||
import { CACHE_INITIALISED_AT } from './constants';
|
||||
import { CACHE_INITIALISED_AT, DECOUPLED_PLUGIN_REGEX, PLUGIN_PATH_REGEX } from './constants';
|
||||
|
||||
const cache: Record<string, CachedPlugin> = {};
|
||||
const cache: Record<string, PluginInfo> = {};
|
||||
|
||||
type CacheablePlugin = {
|
||||
type RegisterPluginInfo = {
|
||||
path: string;
|
||||
version: string;
|
||||
loadingStrategy: PluginLoadingStrategy;
|
||||
};
|
||||
|
||||
type CachedPlugin = Omit<CacheablePlugin, 'path'>;
|
||||
type PluginInfo = Omit<RegisterPluginInfo, 'path'>;
|
||||
|
||||
export function registerPluginInCache({ path, version, loadingStrategy }: CacheablePlugin): void {
|
||||
export function registerPluginInfoInCache({ path, version, loadingStrategy }: RegisterPluginInfo): void {
|
||||
const key = extractCacheKeyFromPath(path);
|
||||
|
||||
if (key && !cache[key]) {
|
||||
@@ -25,7 +25,7 @@ export function registerPluginInCache({ path, version, loadingStrategy }: Cachea
|
||||
}
|
||||
}
|
||||
|
||||
export function invalidatePluginInCache(pluginId: string): void {
|
||||
export function clearPluginInfoInCache(pluginId: string): void {
|
||||
const path = pluginId;
|
||||
if (cache[path]) {
|
||||
delete cache[path];
|
||||
@@ -33,7 +33,7 @@ export function invalidatePluginInCache(pluginId: string): void {
|
||||
clearPluginSettingsCache(pluginId);
|
||||
}
|
||||
|
||||
export function resolveWithCache(url: string, defaultBust = CACHE_INITIALISED_AT): string {
|
||||
export function resolvePluginUrlWithCache(url: string, defaultBust = CACHE_INITIALISED_AT): string {
|
||||
const path = getCacheKey(url);
|
||||
if (!path) {
|
||||
return `${url}?_cache=${defaultBust}`;
|
||||
@@ -43,7 +43,7 @@ export function resolveWithCache(url: string, defaultBust = CACHE_INITIALISED_AT
|
||||
return `${url}?_cache=${bust}`;
|
||||
}
|
||||
|
||||
export function getPluginFromCache(path: string): CachedPlugin | undefined {
|
||||
export function getPluginInfoFromCache(path: string): PluginInfo | undefined {
|
||||
const key = getCacheKey(path);
|
||||
if (!key) {
|
||||
return;
|
||||
@@ -51,17 +51,15 @@ export function getPluginFromCache(path: string): CachedPlugin | undefined {
|
||||
return cache[key];
|
||||
}
|
||||
|
||||
export function extractCacheKeyFromPath(path: string) {
|
||||
const regex = /\/?public\/plugins\/([^\/]+)\//;
|
||||
const match = path.match(regex);
|
||||
export function extractCacheKeyFromPath(path: string): string | null {
|
||||
const match = path.match(PLUGIN_PATH_REGEX);
|
||||
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
|
||||
// Decoupled core plugins can be loaded by alternative paths
|
||||
const decoupledPluginRegex = /\/?public\/app\/plugins\/(?:datasource|panel)\/([^\/]+)\//;
|
||||
const decoupledPluginMatch = path.match(decoupledPluginRegex);
|
||||
const decoupledPluginMatch = path.match(DECOUPLED_PLUGIN_REGEX);
|
||||
|
||||
if (decoupledPluginMatch) {
|
||||
return decoupledPluginMatch[1];
|
||||
@@ -70,8 +68,8 @@ export function extractCacheKeyFromPath(path: string) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function getCacheKey(address: string): string | undefined {
|
||||
const key = Object.keys(cache).find((key) => address.includes(key));
|
||||
function getCacheKey(path: string): string | undefined {
|
||||
const key = Object.keys(cache).find((key) => path.includes(key));
|
||||
if (!key) {
|
||||
return;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { config } from '@grafana/runtime';
|
||||
|
||||
jest.mock('./cache', () => ({
|
||||
resolveWithCache: (url: string) => `${url}?_cache=1234`,
|
||||
jest.mock('./pluginInfoCache', () => ({
|
||||
resolvePluginUrlWithCache: (url: string) => `${url}?_cache=1234`,
|
||||
}));
|
||||
|
||||
import { server } from './pluginLoader.mock';
|
||||
|
||||
@@ -2,8 +2,8 @@ import { config } from '@grafana/runtime';
|
||||
|
||||
import { transformPluginSourceForCDN } from '../cdn/utils';
|
||||
|
||||
import { resolveWithCache } from './cache';
|
||||
import { LOAD_PLUGIN_CSS_REGEX, JS_CONTENT_TYPE_REGEX, SHARED_DEPENDENCY_PREFIX } from './constants';
|
||||
import { resolvePluginUrlWithCache } from './pluginInfoCache';
|
||||
import { SystemJS } from './systemjs';
|
||||
import { SystemJSWithLoaderHooks } from './types';
|
||||
import { isHostedOnCDN } from './utils';
|
||||
@@ -44,13 +44,13 @@ export function decorateSystemJSResolve(
|
||||
(cleanedUrl.endsWith('.js') || cleanedUrl.endsWith('.css')) && !isHostedOnCDN(cleanedUrl);
|
||||
// Add a cache query param for filesystem module.js requests
|
||||
// CDN hosted plugins contain the version in the path so skip
|
||||
return isFileSystemModule ? resolveWithCache(cleanedUrl) : cleanedUrl;
|
||||
return isFileSystemModule ? resolvePluginUrlWithCache(cleanedUrl) : cleanedUrl;
|
||||
} catch (err) {
|
||||
// Provide fallback for plugins that use `loadPluginCss` to load theme styles.
|
||||
if (LOAD_PLUGIN_CSS_REGEX.test(id)) {
|
||||
const resolvedUrl = getLoadPluginCssUrl(id);
|
||||
const url = originalResolve.apply(this, [resolvedUrl, parentUrl]);
|
||||
return resolveWithCache(url);
|
||||
return resolvePluginUrlWithCache(url);
|
||||
}
|
||||
console.warn(`SystemJS: failed to resolve '${id}'`);
|
||||
return id;
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
} from './extensions/registry/setup';
|
||||
import { importPluginModule } from './importer/importPluginModule';
|
||||
import { pluginImporter } from './importer/pluginImporter';
|
||||
import { getPluginFromCache } from './loader/cache';
|
||||
import { getPluginInfoFromCache } from './loader/pluginInfoCache';
|
||||
// SystemJS has to be imported before the sharedDependenciesMap
|
||||
import { SystemJS } from './loader/systemjs';
|
||||
// eslint-disable-next-line import/order
|
||||
@@ -40,7 +40,7 @@ const systemJSPrototype: SystemJSWithLoaderHooks = SystemJS.constructor.prototyp
|
||||
// it will load the plugin using a script tag. The logic that sets loadingStrategy comes from the backend.
|
||||
// See: pkg/services/pluginsintegration/pluginassets/pluginassets.go
|
||||
systemJSPrototype.shouldFetch = function (url) {
|
||||
const pluginInfo = getPluginFromCache(url);
|
||||
const pluginInfo = getPluginInfoFromCache(url);
|
||||
const jsTypeRegEx = /^[^#?]+\.(js)([?#].*)?$/;
|
||||
|
||||
if (!jsTypeRegEx.test(url)) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { PluginType, patchArrayVectorProrotypeMethods } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
|
||||
import { transformPluginSourceForCDN } from '../cdn/utils';
|
||||
import { resolveWithCache } from '../loader/cache';
|
||||
import { resolvePluginUrlWithCache } from '../loader/pluginInfoCache';
|
||||
import { isHostedOnCDN, resolveModulePath } from '../loader/utils';
|
||||
|
||||
import { SandboxEnvironment, SandboxPluginMeta } from './types';
|
||||
@@ -49,7 +49,7 @@ export async function loadScriptIntoSandbox(url: string, sandboxEnv: SandboxEnvi
|
||||
|
||||
export async function getPluginCode(meta: SandboxPluginMeta): Promise<string> {
|
||||
if (isHostedOnCDN(meta.module)) {
|
||||
// Load plugin from CDN, no need for "resolveWithCache" as CDN URLs already include the version
|
||||
// Load plugin from CDN, no need for "resolvePluginUrlWithCache" as CDN URLs already include the version
|
||||
const url = meta.module;
|
||||
const response = await fetch(url);
|
||||
|
||||
@@ -67,9 +67,9 @@ export async function getPluginCode(meta: SandboxPluginMeta): Promise<string> {
|
||||
return pluginCode;
|
||||
} else {
|
||||
let modulePath = resolveModulePath(meta.module);
|
||||
// resolveWithCache will append a query parameter with its version
|
||||
// resolvePluginUrlWithCache will append a query parameter with its version
|
||||
// to ensure correct cached version is served for local plugins
|
||||
const pluginCodeUrl = resolveWithCache(modulePath);
|
||||
const pluginCodeUrl = resolvePluginUrlWithCache(modulePath);
|
||||
const response = await fetch(pluginCodeUrl);
|
||||
|
||||
let pluginCode = await response.text();
|
||||
|
||||
Reference in New Issue
Block a user