Fix N+1 featureFlags (#10371)

## Context
featureFlag query was done for each record returned by the ORM and
transformed in the QueryResultGettersFactory which was causing an N+1
This commit is contained in:
Weiko
2025-02-20 19:32:30 +01:00
committed by GitHub
parent 05d00e6604
commit c0fda41519
2 changed files with 17 additions and 6 deletions

View File

@ -170,6 +170,7 @@ export abstract class GraphqlQueryBaseResolverService<
objectMetadataItemWithFieldMaps, objectMetadataItemWithFieldMaps,
authContext.workspace.id, authContext.workspace.id,
options.objectMetadataMaps, options.objectMetadataMaps,
featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled],
); );
const resultWithGettersArray = Array.isArray(resultWithGetters) const resultWithGettersArray = Array.isArray(resultWithGetters)

View File

@ -18,7 +18,6 @@ import { AttachmentQueryResultGetterHandler } from 'src/engine/api/graphql/works
import { PersonQueryResultGetterHandler } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/person-query-result-getter.handler'; import { PersonQueryResultGetterHandler } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/person-query-result-getter.handler';
import { WorkspaceMemberQueryResultGetterHandler } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/workspace-member-query-result-getter.handler'; import { WorkspaceMemberQueryResultGetterHandler } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/handlers/workspace-member-query-result-getter.handler';
import { CompositeInputTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/composite-input-type-definition.factory'; import { CompositeInputTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/composite-input-type-definition.factory';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { FileService } from 'src/engine/core-modules/file/services/file.service'; import { FileService } from 'src/engine/core-modules/file/services/file.service';
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps'; import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
@ -71,6 +70,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId: string, objectMetadataItemId: string,
objectMetadataMaps: ObjectMetadataMaps, objectMetadataMaps: ObjectMetadataMaps,
workspaceId: string, workspaceId: string,
isNewRelationEnabled: boolean,
): Promise<IConnection<ObjectRecord>> { ): Promise<IConnection<ObjectRecord>> {
return { return {
...connection, ...connection,
@ -82,6 +82,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId, objectMetadataItemId,
objectMetadataMaps, objectMetadataMaps,
workspaceId, workspaceId,
isNewRelationEnabled,
), ),
})), })),
), ),
@ -93,6 +94,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId: string, objectMetadataItemId: string,
objectMetadataMaps: ObjectMetadataMaps, objectMetadataMaps: ObjectMetadataMaps,
workspaceId: string, workspaceId: string,
isNewRelationEnabled: boolean,
) { ) {
return { return {
...result, ...result,
@ -104,6 +106,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId, objectMetadataItemId,
objectMetadataMaps, objectMetadataMaps,
workspaceId, workspaceId,
isNewRelationEnabled,
), ),
), ),
), ),
@ -115,6 +118,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId: string, objectMetadataItemId: string,
objectMetadataMaps: ObjectMetadataMaps, objectMetadataMaps: ObjectMetadataMaps,
workspaceId: string, workspaceId: string,
isNewRelationEnabled: boolean,
) { ) {
return await Promise.all( return await Promise.all(
recordArray.map( recordArray.map(
@ -124,6 +128,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId, objectMetadataItemId,
objectMetadataMaps, objectMetadataMaps,
workspaceId, workspaceId,
isNewRelationEnabled,
), ),
), ),
); );
@ -134,14 +139,10 @@ export class QueryResultGettersFactory {
objectMetadataItemId: string, objectMetadataItemId: string,
objectMetadataMaps: ObjectMetadataMaps, objectMetadataMaps: ObjectMetadataMaps,
workspaceId: string, workspaceId: string,
isNewRelationEnabled: boolean,
): Promise<ObjectRecord> { ): Promise<ObjectRecord> {
const objectMetadataMapItem = objectMetadataMaps.byId[objectMetadataItemId]; const objectMetadataMapItem = objectMetadataMaps.byId[objectMetadataItemId];
const isNewRelationEnabled = await this.featureFlagService.isFeatureEnabled(
FeatureFlagKey.IsNewRelationEnabled,
workspaceId,
);
const handler = this.getHandler(objectMetadataMapItem.nameSingular); const handler = this.getHandler(objectMetadataMapItem.nameSingular);
const relationFields = Object.keys(record) const relationFields = Object.keys(record)
@ -191,6 +192,7 @@ export class QueryResultGettersFactory {
relationObjectMetadataItem.id, relationObjectMetadataItem.id,
objectMetadataMaps, objectMetadataMaps,
workspaceId, workspaceId,
isNewRelationEnabled,
); );
} else { } else {
if (!isDefined(relationField.relationTargetObjectMetadataId)) { if (!isDefined(relationField.relationTargetObjectMetadataId)) {
@ -203,6 +205,7 @@ export class QueryResultGettersFactory {
relationField.relationTargetObjectMetadataId, relationField.relationTargetObjectMetadataId,
objectMetadataMaps, objectMetadataMaps,
workspaceId, workspaceId,
isNewRelationEnabled,
); );
} }
} }
@ -225,6 +228,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId: string, objectMetadataItemId: string,
objectMetadataMaps: ObjectMetadataMaps, objectMetadataMaps: ObjectMetadataMaps,
workspaceId: string, workspaceId: string,
isNewRelationEnabled: boolean,
) { ) {
if (isQueryResultFieldValueAConnection(queryResultField)) { if (isQueryResultFieldValueAConnection(queryResultField)) {
return await this.processConnection( return await this.processConnection(
@ -232,6 +236,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId, objectMetadataItemId,
objectMetadataMaps, objectMetadataMaps,
workspaceId, workspaceId,
isNewRelationEnabled,
); );
} else if (isQueryResultFieldValueANestedRecordArray(queryResultField)) { } else if (isQueryResultFieldValueANestedRecordArray(queryResultField)) {
return await this.processNestedRecordArray( return await this.processNestedRecordArray(
@ -239,6 +244,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId, objectMetadataItemId,
objectMetadataMaps, objectMetadataMaps,
workspaceId, workspaceId,
isNewRelationEnabled,
); );
} else if (isQueryResultFieldValueARecordArray(queryResultField)) { } else if (isQueryResultFieldValueARecordArray(queryResultField)) {
return await this.processRecordArray( return await this.processRecordArray(
@ -246,6 +252,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId, objectMetadataItemId,
objectMetadataMaps, objectMetadataMaps,
workspaceId, workspaceId,
isNewRelationEnabled,
); );
} else if (isQueryResultFieldValueARecord(queryResultField)) { } else if (isQueryResultFieldValueARecord(queryResultField)) {
return await this.processRecord( return await this.processRecord(
@ -253,6 +260,7 @@ export class QueryResultGettersFactory {
objectMetadataItemId, objectMetadataItemId,
objectMetadataMaps, objectMetadataMaps,
workspaceId, workspaceId,
isNewRelationEnabled,
); );
} else { } else {
this.logger.warn( this.logger.warn(
@ -269,12 +277,14 @@ export class QueryResultGettersFactory {
objectMetadataItem: ObjectMetadataInterface, objectMetadataItem: ObjectMetadataInterface,
workspaceId: string, workspaceId: string,
objectMetadataMaps: ObjectMetadataMaps, objectMetadataMaps: ObjectMetadataMaps,
isNewRelationEnabled: boolean,
): Promise<any> { ): Promise<any> {
return await this.processQueryResultField( return await this.processQueryResultField(
result, result,
objectMetadataItem.id, objectMetadataItem.id,
objectMetadataMaps, objectMetadataMaps,
workspaceId, workspaceId,
isNewRelationEnabled,
); );
} }