Add local only cache to cache service and cache typeorm entity metadata (#16287)
## Problem buildEntityMetadatas in GlobalWorkspaceOrmManager is computationally expensive and was running on every executeInWorkspaceContext call. This method uses TypeORM's EntitySchemaTransformer and EntityMetadataBuilder to build metadata for all workspace entities (30-50+ objects with many fields each). The resulting EntityMetadata[] is not serialisable which means it cannot be cached in Redis because they contain: - Circular references - Functions/methods - References to the DataSource instance ## Solution Extended the workspace cache system to support local-only caching, then created a cache provider for entityMetadatas. ## Implementation details Updated @WorkspaceCache decorator (workspace-cache.decorator.ts) - Added localOnly?: boolean option to skip Redis storage for non-serializable data Created WorkspaceEntityMetadatasCacheService - Computes entity metadatas from DB to avoid race condition, this is acceptable Simplified GlobalWorkspaceOrmManager - Now fetches entityMetadatas from cache instead of rebuilding on every call Updated Workspace migration runner - the only entry point where metadata can change - Now invalidate the new 'entityMetadata' local cache when shouldIncrementMetadataGraphqlSchemaVersion is true (== field/object mutations)
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
import { type Milliseconds } from 'cache-manager';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interfaces/node-environment.interface';
|
||||
|
||||
import { type CacheKey } from 'src/engine/twenty-orm/storage/types/cache-key.type';
|
||||
|
||||
type AsyncFactoryCallback<T> = () => Promise<T | null>;
|
||||
@@ -39,13 +37,6 @@ export class PromiseMemoizer<T> {
|
||||
return existingPromise;
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== NodeEnvironment.TEST) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
`Computing new Datasource for cacheKey: ${cacheKey} out of ${this.cache.size}`,
|
||||
);
|
||||
}
|
||||
|
||||
const newPromise = (async () => {
|
||||
try {
|
||||
const value = await factory();
|
||||
|
||||
Reference in New Issue
Block a user