Optimize EntityMetadata caching in GlobalWorkspaceDataSource (#16146)

## Context
EntityMetadata was being rebuilt from scratch on every
findMetadata()/getMetadata() call (~20 times per request). This involved
running EntitySchemaTransformer.transform() and
EntityMetadataBuilder.build() repeatedly, causing unnecessary CPU
overhead.

## Implementation
Cache entityMetadatas in ORMWorkspaceContext: Build EntityMetadata once
during workspace context initialization instead of on every metadata
lookup
Remove redundant entitySchemas caching: Since flatMetadata is already
cached, the additional Redis cache for entitySchemaOptions was
unnecessary overhead
Remove WorkspaceEntitiesStorage: Replaced with direct lookup from
FlatObjectMetadataMap
Simplify getObjectMetadataFromEntityTarget: Now only accepts string
targets, using flat metadata maps directly

Also:
Removed unused injections in some services
This commit is contained in:
Weiko
2025-11-28 10:09:52 +01:00
committed by GitHub
parent fd9ea2f5ee
commit 9620a4b0ba
11 changed files with 45 additions and 148 deletions
@@ -4,7 +4,6 @@ import { isDefined } from 'twenty-shared/utils';
import { type WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { MessageChannelSyncStatusService } from 'src/modules/messaging/common/services/message-channel-sync-status.service';
import {
MessageChannelPendingGroupEmailsAction,
MessageChannelWorkspaceEntity,
@@ -22,7 +21,6 @@ export class MessagingProcessGroupEmailActionsService {
private readonly twentyORMManager: TwentyORMManager,
private readonly messagingDeleteGroupEmailMessagesService: MessagingDeleteGroupEmailMessagesService,
private readonly messagingClearCursorsService: MessagingClearCursorsService,
private readonly messageChannelSyncStatusService: MessageChannelSyncStatusService,
) {}
async markMessageChannelAsPendingGroupEmailsAction(
@@ -1,7 +1,5 @@
import { Injectable } from '@nestjs/common';
import { AuditService } from 'src/engine/core-modules/audit/services/audit.service';
type MessagingMonitoringTrackInput = {
eventName: string;
workspaceId?: string;
@@ -13,7 +11,7 @@ type MessagingMonitoringTrackInput = {
@Injectable()
export class MessagingMonitoringService {
constructor(private readonly _auditService: AuditService) {}
constructor() {}
public async track({
eventName: _eventName,