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:
@@ -63,18 +63,23 @@ export class UserRoleService {
|
||||
userWorkspaceId,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
userWorkspaceId?: string;
|
||||
}): Promise<string | undefined> {
|
||||
if (!isDefined(userWorkspaceId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
userWorkspaceId: string;
|
||||
}): Promise<string> {
|
||||
const { userWorkspaceRoleMap } =
|
||||
await this.workspaceCacheService.getOrRecompute(workspaceId, [
|
||||
'userWorkspaceRoleMap',
|
||||
]);
|
||||
|
||||
return userWorkspaceRoleMap[userWorkspaceId];
|
||||
const roleId = userWorkspaceRoleMap[userWorkspaceId];
|
||||
|
||||
if (!isDefined(roleId)) {
|
||||
throw new PermissionsException(
|
||||
`User workspace ${userWorkspaceId} has no role assigned`,
|
||||
PermissionsExceptionCode.NO_ROLE_FOUND_FOR_USER_WORKSPACE,
|
||||
);
|
||||
}
|
||||
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public async getRolesByUserWorkspaces({
|
||||
|
||||
Reference in New Issue
Block a user