1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-18 21:09:40 +02:00
portainer/app/portainer/services/http-request.helper.ts
Ali 4096bb562d
feat(cache): introduce cache option [EE-6293] (#10672)
Co-authored-by: testa113 <testa113>
2023-11-22 14:21:07 +13:00

102 lines
3.2 KiB
TypeScript

import { AxiosRequestConfig } from 'axios';
export const CACHE_DURATION = 5 * 60 * 1000; // 5m in ms
// event emitted when cache need to be refreshed
// used to sync $http + axios cache clear
export const CACHE_REFRESH_EVENT = '__cache__refresh__event__';
// utility function to dispatch catch refresh event
export function dispatchCacheRefreshEvent() {
dispatchEvent(new CustomEvent(CACHE_REFRESH_EVENT, {}));
}
// perform checks on config.method and config.url
// to dispatch event in only specific scenarios
export function dispatchCacheRefreshEventIfNeeded(req: AxiosRequestConfig) {
if (
req.method &&
['post', 'patch', 'put', 'delete'].includes(req.method.toLowerCase()) &&
// don't clear cache when we try to check for namespaces accesses
// otherwise we will clear it on every page
req.url &&
!req.url.includes('selfsubjectaccessreviews') &&
req.url.includes('kubernetes')
) {
dispatchCacheRefreshEvent();
}
}
interface Headers {
agentTargetQueue: string[];
agentManagerOperation: boolean;
registryAuthentication?: string;
agentTargetLastValue: string;
}
const headers: Headers = {
agentTargetQueue: [],
agentManagerOperation: false,
agentTargetLastValue: '',
};
export function registryAuthenticationHeader() {
return headers.registryAuthentication;
}
export function setRegistryAuthenticationHeader(headerValue: string) {
headers.registryAuthentication = headerValue;
}
// Due to the fact that async HTTP requests are decorated using an interceptor
// we need to store and retrieve the headers using a first-in-first-out (FIFO) data structure.
// Otherwise, sequential HTTP requests might end up using the same header value (incorrect in the case
// of starting multiple containers on different nodes for example).
// To prevent having to use the HttpRequestHelper.setPortainerAgentTargetHeader before EACH request,
// we re-use the latest available header in the data structure (handy in thee case of multiple requests affecting
// the same node in the same view).
export function portainerAgentTargetHeader() {
if (headers.agentTargetQueue.length === 0) {
return headers.agentTargetLastValue;
}
if (headers.agentTargetQueue.length === 1) {
const [lastValue] = headers.agentTargetQueue;
headers.agentTargetLastValue = lastValue;
}
return headers.agentTargetQueue.shift() || '';
}
export function setPortainerAgentTargetHeader(headerValue: string) {
if (headerValue) {
headers.agentTargetQueue.push(headerValue);
}
}
export function setPortainerAgentManagerOperation(set: boolean) {
headers.agentManagerOperation = set;
}
export function portainerAgentManagerOperation() {
return headers.agentManagerOperation;
}
export function resetAgentHeaders() {
headers.agentTargetQueue = [];
headers.agentTargetLastValue = '';
headers.agentManagerOperation = false;
delete headers.registryAuthentication;
}
/* @ngInject */
export function HttpRequestHelperAngular() {
return {
registryAuthenticationHeader,
setRegistryAuthenticationHeader,
portainerAgentTargetHeader,
setPortainerAgentTargetHeader,
setPortainerAgentManagerOperation,
portainerAgentManagerOperation,
resetAgentHeaders,
};
}