Investigate memory leak (#19213)
In search for cache leak + Remove old instrumentation
This commit is contained in:
@@ -5,6 +5,7 @@ import { WorkspaceResolverFactory } from 'src/engine/api/graphql/workspace-resol
|
||||
import { WorkspaceGraphQLSchemaGenerator } from 'src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory';
|
||||
import { WorkspaceSchemaFactory } from 'src/engine/api/graphql/workspace-schema.factory';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { MetricsService } from 'src/engine/core-modules/metrics/metrics.service';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
@@ -54,6 +55,10 @@ describe('WorkspaceSchemaFactory', () => {
|
||||
provide: TwentyConfigService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: MetricsService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { ScalarsExplorerService } from 'src/engine/api/graphql/services/scalars-
|
||||
import { WorkspaceResolverBuilderModule } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module';
|
||||
import { WorkspaceSchemaBuilderModule } from 'src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module';
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { MetricsModule } from 'src/engine/core-modules/metrics/metrics.module';
|
||||
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
@@ -18,6 +19,7 @@ import { WorkspaceSchemaFactory } from './workspace-schema.factory';
|
||||
WorkspaceCacheStorageModule,
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
FeatureFlagModule,
|
||||
MetricsModule,
|
||||
],
|
||||
providers: [WorkspaceSchemaFactory, ScalarsExplorerService],
|
||||
exports: [WorkspaceSchemaFactory],
|
||||
|
||||
-32
@@ -1,5 +1,3 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
|
||||
import { type Request } from 'express';
|
||||
import { DocumentNode, parse } from 'graphql';
|
||||
import { type Plugin } from 'graphql-yoga';
|
||||
@@ -7,15 +5,12 @@ import { FeatureFlagKey } from 'twenty-shared/types';
|
||||
|
||||
import { isNull } from '@sniptt/guards';
|
||||
import { type DirectExecutionService } from 'src/engine/api/graphql/direct-execution/direct-execution.service';
|
||||
import { queryTimingContextStorage } from 'src/engine/core-modules/graphql/storage/query-timing-context.storage';
|
||||
import { computeSkipWorkspaceSchemaCreation } from 'src/engine/api/graphql/direct-execution/utils/compute-skip-workspace-schema-creation.util';
|
||||
import { findOperationDefinition } from 'src/engine/api/graphql/direct-execution/utils/find-operation-definition.util';
|
||||
import { hasOnlyGeneratedWorkspaceResolvers } from 'src/engine/api/graphql/direct-execution/utils/has-only-generated-workspace-resolvers.util';
|
||||
import { isSubscriptionOperation } from 'src/engine/api/graphql/direct-execution/utils/is-subscription-operation.util';
|
||||
import { type FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
|
||||
const logger = new Logger('GraphQLQueryTiming');
|
||||
|
||||
export type DirectExecutionPluginConfig = {
|
||||
directExecutionService: DirectExecutionService;
|
||||
featureFlagService: FeatureFlagService;
|
||||
@@ -89,33 +84,6 @@ export function useDirectExecution(
|
||||
return;
|
||||
}
|
||||
|
||||
const isTimingEnabled = await config.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IS_GRAPHQL_QUERY_TIMING_ENABLED,
|
||||
req.workspace.id,
|
||||
);
|
||||
|
||||
const resolvedOperationName = operationName ?? 'Anonymous';
|
||||
|
||||
if (isTimingEnabled) {
|
||||
const startTime = performance.now();
|
||||
|
||||
const timedResult = await queryTimingContextStorage.run(true, () =>
|
||||
config.directExecutionService.execute(req, document),
|
||||
);
|
||||
|
||||
const durationMs = (performance.now() - startTime).toFixed(2);
|
||||
|
||||
logger.log(
|
||||
`[direct-execution] ${resolvedOperationName} — ${durationMs}ms (workspace: ${req.workspace.id})`,
|
||||
);
|
||||
|
||||
if (isNull(timedResult)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return endResponse(Response.json(timedResult));
|
||||
}
|
||||
|
||||
const result = await config.directExecutionService.execute(req, document);
|
||||
|
||||
if (isNull(result)) {
|
||||
|
||||
+1
-5
@@ -21,18 +21,17 @@ import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interface
|
||||
import { DirectExecutionService } from 'src/engine/api/graphql/direct-execution/direct-execution.service';
|
||||
import { useDirectExecution } from 'src/engine/api/graphql/direct-execution/hooks/use-direct-execution.hook';
|
||||
import { WorkspaceSchemaFactory } from 'src/engine/api/graphql/workspace-schema.factory';
|
||||
import { type FlatAuthContextUser } from 'src/engine/core-modules/auth/types/flat-auth-context-user.type';
|
||||
import { CoreEngineModule } from 'src/engine/core-modules/core-engine.module';
|
||||
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||
import { useSentryTracing } from 'src/engine/core-modules/exception-handler/hooks/use-sentry-tracing';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { useDisableIntrospectionAndSuggestionsForUnauthenticatedUsers } from 'src/engine/core-modules/graphql/hooks/use-disable-introspection-and-suggestions-for-unauthenticated-users.hook';
|
||||
import { useGraphQLErrorHandlerHook } from 'src/engine/core-modules/graphql/hooks/use-graphql-error-handler.hook';
|
||||
import { useGraphQLQueryTiming } from 'src/engine/core-modules/graphql/hooks/use-graphql-query-timing.hook';
|
||||
import { useValidateGraphqlQueryComplexity } from 'src/engine/core-modules/graphql/hooks/use-validate-graphql-query-complexity.hook';
|
||||
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
import { MetricsService } from 'src/engine/core-modules/metrics/metrics.service';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { type FlatAuthContextUser } from 'src/engine/core-modules/auth/types/flat-auth-context-user.type';
|
||||
import { type FlatWorkspace } from 'src/engine/core-modules/workspace/types/flat-workspace.type';
|
||||
import { DataloaderService } from 'src/engine/dataloaders/dataloader.service';
|
||||
import { handleExceptionAndConvertToGraphQLError } from 'src/engine/utils/global-exception-handler.util';
|
||||
@@ -62,9 +61,6 @@ export class GraphQLConfigService
|
||||
const isDebugMode =
|
||||
this.twentyConfigService.get('NODE_ENV') === NodeEnvironment.DEVELOPMENT;
|
||||
const plugins = [
|
||||
useGraphQLQueryTiming({
|
||||
featureFlagService: this.featureFlagService,
|
||||
}),
|
||||
useDirectExecution({
|
||||
directExecutionService: this.directExecutionService,
|
||||
featureFlagService: this.featureFlagService,
|
||||
|
||||
@@ -5,13 +5,12 @@ import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interface
|
||||
|
||||
import { useCachedMetadata } from 'src/engine/api/graphql/graphql-config/hooks/use-cached-metadata';
|
||||
import { MetadataGraphQLApiModule } from 'src/engine/api/graphql/metadata-graphql-api.module';
|
||||
import { ClientConfig } from 'src/engine/core-modules/client-config/client-config.entity';
|
||||
import { type CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
|
||||
import { ClientConfig } from 'src/engine/core-modules/client-config/client-config.entity';
|
||||
import { type ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||
import { type FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { useDisableIntrospectionAndSuggestionsForUnauthenticatedUsers } from 'src/engine/core-modules/graphql/hooks/use-disable-introspection-and-suggestions-for-unauthenticated-users.hook';
|
||||
import { useGraphQLErrorHandlerHook } from 'src/engine/core-modules/graphql/hooks/use-graphql-error-handler.hook';
|
||||
import { useGraphQLQueryTiming } from 'src/engine/core-modules/graphql/hooks/use-graphql-query-timing.hook';
|
||||
import { useValidateGraphqlQueryComplexity } from 'src/engine/core-modules/graphql/hooks/use-validate-graphql-query-complexity.hook';
|
||||
import { type I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
import { type MetricsService } from 'src/engine/core-modules/metrics/metrics.service';
|
||||
@@ -40,7 +39,6 @@ export const metadataModuleFactory = async (
|
||||
},
|
||||
resolvers: { JSON: GraphQLJSON },
|
||||
plugins: [
|
||||
useGraphQLQueryTiming({ featureFlagService }),
|
||||
useGraphQLErrorHandlerHook({
|
||||
metricsService: metricsService,
|
||||
exceptionHandlerService,
|
||||
|
||||
@@ -12,6 +12,8 @@ import { workspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/work
|
||||
import { WorkspaceResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory';
|
||||
import { WorkspaceGraphQLSchemaGenerator } from 'src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { MetricsService } from 'src/engine/core-modules/metrics/metrics.service';
|
||||
import { MetricsKeys } from 'src/engine/core-modules/metrics/types/metrics-keys.type';
|
||||
import { FlatWorkspace } from 'src/engine/core-modules/workspace/types/flat-workspace.type';
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
import {
|
||||
@@ -38,6 +40,7 @@ export class WorkspaceSchemaFactory {
|
||||
private readonly workspaceManyOrAllFlatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
private readonly dataSourceService: DataSourceService,
|
||||
private readonly metricsService: MetricsService,
|
||||
) {}
|
||||
|
||||
async createGraphQLSchema(
|
||||
@@ -203,6 +206,11 @@ export class WorkspaceSchemaFactory {
|
||||
},
|
||||
});
|
||||
|
||||
await this.metricsService.incrementCounter({
|
||||
key: MetricsKeys.GraphqlSchemaBuild,
|
||||
shouldStoreInCache: false,
|
||||
});
|
||||
|
||||
return executableSchema;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user