Optimize EntityMetadata caching in GlobalWorkspaceDataSource#16146
Optimize EntityMetadata caching in GlobalWorkspaceDataSource#16146
Conversation
Greptile OverviewGreptile SummaryThis PR significantly improves performance by caching Key improvements:
The implementation correctly uses Confidence Score: 5/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant Request
participant GlobalWorkspaceOrmManager
participant Cache as Various Cache Services
participant EntitySchemaFactory
participant TypeORM as TypeORM Builders
participant Context as ORMWorkspaceContext
participant DataSource as GlobalWorkspaceDataSource
Request->>GlobalWorkspaceOrmManager: executeInWorkspaceContext(authContext)
GlobalWorkspaceOrmManager->>GlobalWorkspaceOrmManager: loadWorkspaceContext(authContext)
GlobalWorkspaceOrmManager->>Cache: getOrRecomputeManyOrAllFlatEntityMaps()
Cache-->>GlobalWorkspaceOrmManager: flatObjectMetadataMaps, flatFieldMetadataMaps, flatIndexMaps
GlobalWorkspaceOrmManager->>Cache: getWorkspaceFeatureFlagsMapAndVersion()
Cache-->>GlobalWorkspaceOrmManager: featureFlagsMap
GlobalWorkspaceOrmManager->>Cache: getRolesPermissionsFromCache()
Cache-->>GlobalWorkspaceOrmManager: permissionsPerRoleId
GlobalWorkspaceOrmManager->>GlobalWorkspaceOrmManager: buildEntitySchemas()
loop For each flatObjectMetadata
GlobalWorkspaceOrmManager->>EntitySchemaFactory: create(workspaceId, flatObjectMetadata)
EntitySchemaFactory-->>GlobalWorkspaceOrmManager: EntitySchema
end
GlobalWorkspaceOrmManager->>GlobalWorkspaceOrmManager: buildEntityMetadatas(entitySchemas)
GlobalWorkspaceOrmManager->>TypeORM: EntitySchemaTransformer.transform(entitySchemas)
TypeORM-->>GlobalWorkspaceOrmManager: metadataArgsStorage
GlobalWorkspaceOrmManager->>TypeORM: EntityMetadataBuilder.build()
TypeORM-->>GlobalWorkspaceOrmManager: entityMetadatas[]
GlobalWorkspaceOrmManager->>Context: Store in ORMWorkspaceContext
Note over Context: entityMetadatas cached here<br/>for entire request lifecycle
GlobalWorkspaceOrmManager->>GlobalWorkspaceOrmManager: withWorkspaceContext(context, fn)
loop Multiple times per request (~20x)
Request->>DataSource: findMetadata(target) or getMetadata(target)
DataSource->>Context: getWorkspaceContext()
Context-->>DataSource: { entityMetadatas }
DataSource->>DataSource: entityMetadatas.find(metadata => metadata.target === target)
DataSource-->>Request: EntityMetadata (cached)
Note over DataSource: No rebuild needed!<br/>Direct array lookup
end
|
|
🚀 Preview Environment Ready! Your preview environment is available at: http://bore.pub:14435 This environment will automatically shut down when the PR is closed or after 5 hours. |
| entityTarget: EntityTarget<T>, | ||
| internalContext: WorkspaceInternalContext, | ||
| ): FlatObjectMetadata => { | ||
| const objectMetadataName = |
There was a problem hiding this comment.
I've double checked, it seems this is never reached as an entityTarget but always as a string. I'm keeping the signature as it is for now and throwing to catch early if I'm wrong but otherwise this should simplify this part where WorkspaceEntitiesStorage can be completely deprecated
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