From 614a81860f4ac01c52d3673a791db6e372ab714a Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Wed, 21 Aug 2024 11:48:20 +0200 Subject: [PATCH] Add logging on currentWorkspaceMember query (#6706) We are experiencing slow GetCurrentUser endpoint, this is helping us troubleshoot --- .../database/typeorm/core/core.datasource.ts | 2 +- .../user/services/user.service.ts | 17 +++++++++- .../engine/core-modules/user/user.resolver.ts | 5 +++ .../entity-manager/entity.manager.ts | 1 + .../factories/workspace-datasource.factory.ts | 32 +++++++++++++------ .../twenty-orm/twenty-orm-global.manager.ts | 10 +++++- 6 files changed, 55 insertions(+), 12 deletions(-) diff --git a/packages/twenty-server/src/database/typeorm/core/core.datasource.ts b/packages/twenty-server/src/database/typeorm/core/core.datasource.ts index 6733370d0..1260f9bcf 100644 --- a/packages/twenty-server/src/database/typeorm/core/core.datasource.ts +++ b/packages/twenty-server/src/database/typeorm/core/core.datasource.ts @@ -1,7 +1,7 @@ import { TypeOrmModuleOptions } from '@nestjs/typeorm'; -import { DataSource, DataSourceOptions } from 'typeorm'; import { config } from 'dotenv'; +import { DataSource, DataSourceOptions } from 'typeorm'; config(); export const typeORMCoreModuleOptions: TypeOrmModuleOptions = { diff --git a/packages/twenty-server/src/engine/core-modules/user/services/user.service.ts b/packages/twenty-server/src/engine/core-modules/user/services/user.service.ts index 3ee3636ee..6c42f93b2 100644 --- a/packages/twenty-server/src/engine/core-modules/user/services/user.service.ts +++ b/packages/twenty-server/src/engine/core-modules/user/services/user.service.ts @@ -40,18 +40,24 @@ export class UserService extends TypeOrmQueryService { return null; } + console.time('loadWorkspaceMember repo'); const workspaceMemberRepository = await this.twentyORMGlobalManager.getRepositoryForWorkspace( user.defaultWorkspaceId, 'workspaceMember', ); + console.timeEnd('loadWorkspaceMember repo'); + + console.time('loadWorkspaceMember find'); const workspaceMember = await workspaceMemberRepository.findOne({ where: { userId: user.id, }, }); + console.timeEnd('loadWorkspaceMember find'); + return workspaceMember; } @@ -60,13 +66,22 @@ export class UserService extends TypeOrmQueryService { return []; } + console.time('loadWorkspaceMembers repo'); const workspaceMemberRepository = await this.twentyORMGlobalManager.getRepositoryForWorkspace( workspace.id, 'workspaceMember', ); - return workspaceMemberRepository.find(); + console.timeEnd('loadWorkspaceMembers repo'); + + console.time('loadWorkspaceMembers find'); + + const workspaceMembers = workspaceMemberRepository.find(); + + console.timeEnd('loadWorkspaceMembers find'); + + return workspaceMembers; } async deleteUser(userId: string): Promise { diff --git a/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts index c77bb690b..b91140621 100644 --- a/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts @@ -98,6 +98,7 @@ export class UserResolver { nullable: true, }) async workspaceMember(@Parent() user: User): Promise { + console.time('resolver workspaceMember'); const workspaceMember = await this.userService.loadWorkspaceMember(user); if (workspaceMember && workspaceMember.avatarUrl) { @@ -108,6 +109,7 @@ export class UserResolver { workspaceMember.avatarUrl = `${workspaceMember.avatarUrl}?token=${avatarUrlToken}`; } + console.timeEnd('resolver workspaceMember'); // TODO: Fix typing disrepency between Entity and DTO return workspaceMember as WorkspaceMember | null; @@ -117,6 +119,7 @@ export class UserResolver { nullable: true, }) async workspaceMembers(@Parent() user: User): Promise { + console.time('resolver workspaceMembers'); const workspaceMembers = await this.userService.loadWorkspaceMembers( user.defaultWorkspace, ); @@ -132,6 +135,8 @@ export class UserResolver { } } + console.timeEnd('resolver workspaceMembers'); + // TODO: Fix typing disrepency between Entity and DTO return workspaceMembers as WorkspaceMember[]; } diff --git a/packages/twenty-server/src/engine/twenty-orm/entity-manager/entity.manager.ts b/packages/twenty-server/src/engine/twenty-orm/entity-manager/entity.manager.ts index 4be629755..66f03915f 100644 --- a/packages/twenty-server/src/engine/twenty-orm/entity-manager/entity.manager.ts +++ b/packages/twenty-server/src/engine/twenty-orm/entity-manager/entity.manager.ts @@ -26,6 +26,7 @@ export class WorkspaceEntityManager extends EntityManager { target: EntityTarget, ): WorkspaceRepository { // find already created repository instance and return it if found + const repoFromMap = this.repositories.get(target); if (repoFromMap) { diff --git a/packages/twenty-server/src/engine/twenty-orm/factories/workspace-datasource.factory.ts b/packages/twenty-server/src/engine/twenty-orm/factories/workspace-datasource.factory.ts index 10daedc7d..1a1b92a28 100644 --- a/packages/twenty-server/src/engine/twenty-orm/factories/workspace-datasource.factory.ts +++ b/packages/twenty-server/src/engine/twenty-orm/factories/workspace-datasource.factory.ts @@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { EntitySchema, Repository } from 'typeorm'; +import { v4 } from 'uuid'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; @@ -28,11 +29,19 @@ export class WorkspaceDatasourceFactory { workspaceId: string, workspaceMetadataVersion: string | null, ): Promise { - const desiredWorkspaceMetadataVersion = - workspaceMetadataVersion ?? - (await this.workspaceMetadataVersionService.getMetadataVersion( + const logId = v4(); + + console.time(`fetch in datasource factory ${logId}`); + + const latestWorkspaceMetadataVersion = + await this.workspaceMetadataVersionService.getMetadataVersion( workspaceId, - )); + ); + + console.timeEnd(`fetch in datasource factory ${logId}`); + + const desiredWorkspaceMetadataVersion = + workspaceMetadataVersion ?? latestWorkspaceMetadataVersion; if (!desiredWorkspaceMetadataVersion) { throw new Error( @@ -40,11 +49,6 @@ export class WorkspaceDatasourceFactory { ); } - const latestWorkspaceMetadataVersion = - await this.workspaceMetadataVersionService.getMetadataVersion( - workspaceId, - ); - if (latestWorkspaceMetadataVersion !== desiredWorkspaceMetadataVersion) { throw new Error( `Workspace metadata version mismatch detected for workspace ${workspaceId}. Current version: ${latestWorkspaceMetadataVersion}. Desired version: ${desiredWorkspaceMetadataVersion}`, @@ -80,6 +84,9 @@ export class WorkspaceDatasourceFactory { const workspaceDataSource = await workspaceDataSourceCacheInstance.execute( `${workspaceId}-${latestWorkspaceMetadataVersion}`, async () => { + const logId = v4(); + + console.log('Creating workspace fresh data source...' + logId); const dataSourceMetadata = await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceId( workspaceId, @@ -97,6 +104,7 @@ export class WorkspaceDatasourceFactory { ); } + console.time('create entity schema' + logId); const cachedEntitySchemaOptions = await this.workspaceCacheStorageService.getORMEntitySchema( workspaceId, @@ -122,7 +130,9 @@ export class WorkspaceDatasourceFactory { cachedEntitySchemas = entitySchemas; } + console.timeEnd('create entity schema' + logId); + console.time('create workspace data source' + logId); const workspaceDataSource = new WorkspaceDataSource( { workspaceId, @@ -146,7 +156,11 @@ export class WorkspaceDatasourceFactory { }, ); + console.timeEnd('create workspace data source' + logId); + + console.time('initialize workspace data source' + logId); await workspaceDataSource.initialize(); + console.timeEnd('initialize workspace data source' + logId); return workspaceDataSource; }, diff --git a/packages/twenty-server/src/engine/twenty-orm/twenty-orm-global.manager.ts b/packages/twenty-server/src/engine/twenty-orm/twenty-orm-global.manager.ts index add735169..6d24e6f8e 100644 --- a/packages/twenty-server/src/engine/twenty-orm/twenty-orm-global.manager.ts +++ b/packages/twenty-server/src/engine/twenty-orm/twenty-orm-global.manager.ts @@ -1,6 +1,7 @@ import { Injectable, Type } from '@nestjs/common'; import { ObjectLiteral } from 'typeorm'; +import { v4 } from 'uuid'; import { WorkspaceDatasourceFactory } from 'src/engine/twenty-orm/factories/workspace-datasource.factory'; import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository'; @@ -36,12 +37,19 @@ export class TwentyORMGlobalManager { ); } + const logId = v4(); + + console.time(`createDataSource in orm ${logId}`); const workspaceDataSource = await this.workspaceDataSourceFactory.create( workspaceId, null, ); - return workspaceDataSource.getRepository(objectMetadataName); + console.timeEnd(`createDataSource in orm ${logId}`); + + const repository = workspaceDataSource.getRepository(objectMetadataName); + + return repository; } async getDataSourceForWorkspace(workspaceId: string) {