Add timestamps to cache entries and server events (#19976)
This commit is contained in:
@@ -9,7 +9,7 @@ import {
|
||||
} from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import {
|
||||
UmbManagementApiDetailDataRequestManager,
|
||||
UmbManagementApiInflightRequestCache,
|
||||
UmbManagementApiInFlightRequestCache,
|
||||
} from '@umbraco-cms/backoffice/management-api';
|
||||
|
||||
export class UmbManagementApiDataTypeDetailDataRequestManager extends UmbManagementApiDetailDataRequestManager<
|
||||
@@ -17,7 +17,7 @@ export class UmbManagementApiDataTypeDetailDataRequestManager extends UmbManagem
|
||||
UpdateDataTypeRequestModel,
|
||||
CreateDataTypeRequestModel
|
||||
> {
|
||||
static #inflightRequestCache = new UmbManagementApiInflightRequestCache<DataTypeResponseModel>();
|
||||
static #inflightRequestCache = new UmbManagementApiInFlightRequestCache<DataTypeResponseModel>();
|
||||
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, {
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import {
|
||||
UmbManagementApiDetailDataRequestManager,
|
||||
UmbManagementApiInflightRequestCache,
|
||||
UmbManagementApiInFlightRequestCache,
|
||||
} from '@umbraco-cms/backoffice/management-api';
|
||||
|
||||
export class UmbManagementApiDocumentTypeDetailDataRequestManager extends UmbManagementApiDetailDataRequestManager<
|
||||
@@ -17,7 +17,7 @@ export class UmbManagementApiDocumentTypeDetailDataRequestManager extends UmbMan
|
||||
UpdateDocumentTypeRequestModel,
|
||||
CreateDocumentTypeRequestModel
|
||||
> {
|
||||
static #inflightRequestCache = new UmbManagementApiInflightRequestCache<DocumentTypeResponseModel>();
|
||||
static #inflightRequestCache = new UmbManagementApiInFlightRequestCache<DocumentTypeResponseModel>();
|
||||
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Keep internal
|
||||
interface UmbCacheEntryModel<DetailDataModelType> {
|
||||
interface UmbDetailCacheEntryModel<DetailDataModelType> {
|
||||
id: string;
|
||||
data: DetailDataModelType;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -10,7 +11,7 @@ interface UmbCacheEntryModel<DetailDataModelType> {
|
||||
* @template DetailDataModelType
|
||||
*/
|
||||
export class UmbManagementApiDetailDataCache<DetailDataModelType> {
|
||||
#entries: Map<string, UmbCacheEntryModel<DetailDataModelType>> = new Map();
|
||||
#entries: Map<string, UmbDetailCacheEntryModel<DetailDataModelType>> = new Map();
|
||||
|
||||
/**
|
||||
* Checks if an entry exists in the cache
|
||||
@@ -29,9 +30,10 @@ export class UmbManagementApiDetailDataCache<DetailDataModelType> {
|
||||
* @memberof UmbManagementApiDetailDataCache
|
||||
*/
|
||||
set(id: string, data: DetailDataModelType): void {
|
||||
const cacheEntry: UmbCacheEntryModel<DetailDataModelType> = {
|
||||
const cacheEntry: UmbDetailCacheEntryModel<DetailDataModelType> = {
|
||||
id: id,
|
||||
data,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
this.#entries.set(id, cacheEntry);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UMB_MANAGEMENT_API_SERVER_EVENT_CONTEXT } from '../server-event/constants.js';
|
||||
import type { UmbManagementApiInflightRequestCache } from '../inflight-request/cache.js';
|
||||
import type { UmbManagementApiInFlightRequestCache } from '../inflight-request/cache.js';
|
||||
import type { UmbManagementApiDetailDataCache } from './cache.js';
|
||||
import {
|
||||
tryExecute,
|
||||
@@ -21,7 +21,7 @@ export interface UmbManagementApiDetailDataRequestManagerArgs<
|
||||
update: (id: string, data: UpdateRequestModelType) => Promise<UmbApiResponse<{ data: unknown }>>;
|
||||
delete: (id: string) => Promise<UmbApiResponse<{ data: unknown }>>;
|
||||
dataCache: UmbManagementApiDetailDataCache<DetailResponseModelType>;
|
||||
inflightRequestCache: UmbManagementApiInflightRequestCache<DetailResponseModelType>;
|
||||
inflightRequestCache: UmbManagementApiInFlightRequestCache<DetailResponseModelType>;
|
||||
}
|
||||
|
||||
export class UmbManagementApiDetailDataRequestManager<
|
||||
@@ -30,7 +30,7 @@ export class UmbManagementApiDetailDataRequestManager<
|
||||
UpdateRequestModelType,
|
||||
> extends UmbControllerBase {
|
||||
#dataCache: UmbManagementApiDetailDataCache<DetailResponseModelType>;
|
||||
#inflightRequestCache: UmbManagementApiInflightRequestCache<DetailResponseModelType>;
|
||||
#inflightRequestCache: UmbManagementApiInFlightRequestCache<DetailResponseModelType>;
|
||||
|
||||
#create;
|
||||
#read;
|
||||
@@ -86,11 +86,13 @@ export class UmbManagementApiDetailDataRequestManager<
|
||||
const hasInflightRequest = this.#inflightRequestCache.has(inflightCacheKey);
|
||||
|
||||
const request = hasInflightRequest
|
||||
? this.#inflightRequestCache.get(inflightCacheKey)
|
||||
? this.#inflightRequestCache.get(inflightCacheKey)?.requestPromise
|
||||
: tryExecute(this, this.#read(id));
|
||||
|
||||
if (!request) {
|
||||
throw new Error(`Failed to create or retrieve 'read' request for ID: ${id} (cache key: ${inflightCacheKey}). Aborting read.`);
|
||||
throw new Error(
|
||||
`Failed to create or retrieve 'read' request for ID: ${id} (cache key: ${inflightCacheKey}). Aborting read.`,
|
||||
);
|
||||
}
|
||||
|
||||
this.#inflightRequestCache.set(inflightCacheKey, request);
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import type { UmbApiResponse } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
interface UmbInFlightRequestCacheEntryModel<ResponseModelType> {
|
||||
key: string;
|
||||
requestPromise: Promise<RequestResolvedType<ResponseModelType>>;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
// Keep internal
|
||||
type RequestResolvedType<ResponseModelType> = UmbApiResponse<{ data?: ResponseModelType }>;
|
||||
|
||||
@@ -8,8 +14,8 @@ type RequestResolvedType<ResponseModelType> = UmbApiResponse<{ data?: ResponseMo
|
||||
* @class UmbManagementApiInflightRequestCache
|
||||
* @template ResponseModelType
|
||||
*/
|
||||
export class UmbManagementApiInflightRequestCache<ResponseModelType> {
|
||||
#entries = new Map<string, Promise<RequestResolvedType<ResponseModelType>>>();
|
||||
export class UmbManagementApiInFlightRequestCache<ResponseModelType> {
|
||||
#entries = new Map<string, UmbInFlightRequestCacheEntryModel<ResponseModelType>>();
|
||||
|
||||
/**
|
||||
* Checks if an entry exists in the cache
|
||||
@@ -28,7 +34,11 @@ export class UmbManagementApiInflightRequestCache<ResponseModelType> {
|
||||
* @memberof UmbManagementApiInflightRequestCache
|
||||
*/
|
||||
set(key: string, promise: Promise<RequestResolvedType<ResponseModelType>>): void {
|
||||
this.#entries.set(key, promise);
|
||||
this.#entries.set(key, {
|
||||
key,
|
||||
requestPromise: promise,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +47,7 @@ export class UmbManagementApiInflightRequestCache<ResponseModelType> {
|
||||
* @returns {Promise<RequestResolvedType<ResponseModelType>> | undefined} - The cached promise or undefined if not found
|
||||
* @memberof UmbManagementApiInflightRequestCache
|
||||
*/
|
||||
get(key: string): Promise<RequestResolvedType<ResponseModelType>> | undefined {
|
||||
get(key: string): UmbInFlightRequestCacheEntryModel<ResponseModelType> | undefined {
|
||||
return this.#entries.get(key);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Keep internal
|
||||
interface UmbCacheEntryModel<ItemDataModelType> {
|
||||
interface UmbItemCacheEntryModel<ItemDataModelType> {
|
||||
id: string;
|
||||
data: ItemDataModelType;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -10,7 +11,7 @@ interface UmbCacheEntryModel<ItemDataModelType> {
|
||||
* @template ItemDataModelType
|
||||
*/
|
||||
export class UmbManagementApiItemDataCache<ItemDataModelType> {
|
||||
#entries: Map<string, UmbCacheEntryModel<ItemDataModelType>> = new Map();
|
||||
#entries: Map<string, UmbItemCacheEntryModel<ItemDataModelType>> = new Map();
|
||||
|
||||
/**
|
||||
* Checks if an entry exists in the cache
|
||||
@@ -29,9 +30,10 @@ export class UmbManagementApiItemDataCache<ItemDataModelType> {
|
||||
* @memberof UmbManagementApiItemDataCache
|
||||
*/
|
||||
set(id: string, data: ItemDataModelType): void {
|
||||
const cacheEntry: UmbCacheEntryModel<ItemDataModelType> = {
|
||||
const cacheEntry: UmbItemCacheEntryModel<ItemDataModelType> = {
|
||||
id: id,
|
||||
data,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
this.#entries.set(id, cacheEntry);
|
||||
|
||||
@@ -94,8 +94,13 @@ export class UmbManagementApiServerEventContext extends UmbContextBase {
|
||||
})
|
||||
.build();
|
||||
|
||||
this.#connection.on('notify', (payload: UmbManagementApiServerEventModel) => {
|
||||
this.#events.next(payload);
|
||||
this.#connection.on('notify', (payload) => {
|
||||
const event: UmbManagementApiServerEventModel = {
|
||||
...payload,
|
||||
clientTimestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
this.#events.next(event);
|
||||
});
|
||||
|
||||
this.#connection
|
||||
|
||||
@@ -2,4 +2,5 @@ export interface UmbManagementApiServerEventModel {
|
||||
eventSource: string;
|
||||
eventType: string;
|
||||
key: string;
|
||||
clientTimestamp: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user