Fix performance issue mail (#5780)
In this PR, I'm mainly doing two things: - uniformizing messaging-messages-import and messaging-message-list-fetch behaviors (cron.job and job) - improving performances of these cron.jobs by not triggering the jobs if the stage is not relevant - making sure these jobs have same signature (workspaceId + messageChannelId)
This commit is contained in:
@ -12,7 +12,10 @@ import { MessageQueueService } from 'src/engine/integrations/message-queue/servi
|
||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
import { MessageChannelRepository } from 'src/modules/messaging/common/repositories/message-channel.repository';
|
||||
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
import {
|
||||
MessageChannelSyncStage,
|
||||
MessageChannelWorkspaceEntity,
|
||||
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
import {
|
||||
MessagingMessageListFetchJobData,
|
||||
MessagingMessageListFetchJob,
|
||||
@ -59,35 +62,26 @@ export class MessagingMessageListFetchCronJob
|
||||
);
|
||||
|
||||
for (const workspaceId of workspaceIdsWithDataSources) {
|
||||
await this.enqueueSyncs(workspaceId);
|
||||
}
|
||||
}
|
||||
|
||||
private async enqueueSyncs(workspaceId: string): Promise<void> {
|
||||
try {
|
||||
const messageChannels =
|
||||
await this.messageChannelRepository.getAll(workspaceId);
|
||||
|
||||
for (const messageChannel of messageChannels) {
|
||||
if (!messageChannel?.isSyncEnabled) {
|
||||
continue;
|
||||
if (
|
||||
(messageChannel.isSyncEnabled &&
|
||||
messageChannel.syncStage ===
|
||||
MessageChannelSyncStage.PARTIAL_MESSAGE_LIST_FETCH_PENDING) ||
|
||||
messageChannel.syncStage ===
|
||||
MessageChannelSyncStage.FULL_MESSAGE_LIST_FETCH_PENDING
|
||||
) {
|
||||
await this.messageQueueService.add<MessagingMessageListFetchJobData>(
|
||||
MessagingMessageListFetchJob.name,
|
||||
{
|
||||
workspaceId,
|
||||
messageChannelId: messageChannel.id,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
await this.messageQueueService.add<MessagingMessageListFetchJobData>(
|
||||
MessagingMessageListFetchJob.name,
|
||||
{
|
||||
workspaceId,
|
||||
connectedAccountId: messageChannel.connectedAccountId,
|
||||
},
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Error while fetching workspace messages for workspace ${workspaceId}`,
|
||||
);
|
||||
this.logger.error(error);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository, In } from 'typeorm';
|
||||
@ -14,13 +14,17 @@ import {
|
||||
MessagingMessagesImportJobData,
|
||||
MessagingMessagesImportJob,
|
||||
} from 'src/modules/messaging/message-import-manager/jobs/messaging-messages-import.job';
|
||||
import { MessageChannelRepository } from 'src/modules/messaging/common/repositories/message-channel.repository';
|
||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||
import {
|
||||
MessageChannelSyncStage,
|
||||
MessageChannelWorkspaceEntity,
|
||||
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
export class MessagingMessagesImportCronJob
|
||||
implements MessageQueueJob<undefined>
|
||||
{
|
||||
private readonly logger = new Logger(MessagingMessagesImportCronJob.name);
|
||||
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
private readonly workspaceRepository: Repository<Workspace>,
|
||||
@ -29,6 +33,8 @@ export class MessagingMessagesImportCronJob
|
||||
private readonly environmentService: EnvironmentService,
|
||||
@Inject(MessageQueue.messagingQueue)
|
||||
private readonly messageQueueService: MessageQueueService,
|
||||
@InjectObjectMetadataRepository(MessageChannelWorkspaceEntity)
|
||||
private readonly messageChannelRepository: MessageChannelRepository,
|
||||
) {}
|
||||
|
||||
async handle(): Promise<void> {
|
||||
@ -54,12 +60,24 @@ export class MessagingMessagesImportCronJob
|
||||
);
|
||||
|
||||
for (const workspaceId of workspaceIdsWithDataSources) {
|
||||
await this.messageQueueService.add<MessagingMessagesImportJobData>(
|
||||
MessagingMessagesImportJob.name,
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
const messageChannels =
|
||||
await this.messageChannelRepository.getAll(workspaceId);
|
||||
|
||||
for (const messageChannel of messageChannels) {
|
||||
if (
|
||||
messageChannel.isSyncEnabled &&
|
||||
messageChannel.syncStage ===
|
||||
MessageChannelSyncStage.MESSAGES_IMPORT_PENDING
|
||||
) {
|
||||
await this.messageQueueService.add<MessagingMessagesImportJobData>(
|
||||
MessagingMessagesImportJob.name,
|
||||
{
|
||||
workspaceId,
|
||||
messageChannelId: messageChannel.id,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,8 +16,8 @@ import { MessagingGmailPartialMessageListFetchService } from 'src/modules/messag
|
||||
import { isThrottled } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-throttled';
|
||||
|
||||
export type MessagingMessageListFetchJobData = {
|
||||
messageChannelId: string;
|
||||
workspaceId: string;
|
||||
connectedAccountId: string;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
@ -37,42 +37,36 @@ export class MessagingMessageListFetchJob
|
||||
) {}
|
||||
|
||||
async handle(data: MessagingMessageListFetchJobData): Promise<void> {
|
||||
const { workspaceId, connectedAccountId } = data;
|
||||
const { messageChannelId, workspaceId } = data;
|
||||
|
||||
await this.messagingTelemetryService.track({
|
||||
eventName: 'message_list_fetch_job.triggered',
|
||||
messageChannelId,
|
||||
workspaceId,
|
||||
connectedAccountId,
|
||||
});
|
||||
|
||||
const connectedAccount = await this.connectedAccountRepository.getById(
|
||||
connectedAccountId,
|
||||
const messageChannel = await this.messageChannelRepository.getById(
|
||||
messageChannelId,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
if (!connectedAccount) {
|
||||
if (!messageChannel) {
|
||||
await this.messagingTelemetryService.track({
|
||||
eventName: 'message_list_fetch_job.error.connected_account_not_found',
|
||||
eventName: 'message_list_fetch_job.error.message_channel_not_found',
|
||||
messageChannelId,
|
||||
workspaceId,
|
||||
connectedAccountId,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const messageChannel =
|
||||
await this.messageChannelRepository.getFirstByConnectedAccountId(
|
||||
connectedAccountId,
|
||||
const connectedAccount =
|
||||
await this.connectedAccountRepository.getByIdOrFail(
|
||||
messageChannel.connectedAccountId,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
if (!messageChannel) {
|
||||
await this.messagingTelemetryService.track({
|
||||
eventName: 'message_list_fetch_job.error.message_channel_not_found',
|
||||
workspaceId,
|
||||
connectedAccountId,
|
||||
});
|
||||
|
||||
if (!messageChannel?.isSyncEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -88,13 +82,13 @@ export class MessagingMessageListFetchJob
|
||||
switch (messageChannel.syncStage) {
|
||||
case MessageChannelSyncStage.PARTIAL_MESSAGE_LIST_FETCH_PENDING:
|
||||
this.logger.log(
|
||||
`Fetching partial message list for workspace ${workspaceId} and account ${connectedAccount.id}`,
|
||||
`Fetching partial message list for workspace ${workspaceId} and messageChannelId ${messageChannel.id}`,
|
||||
);
|
||||
|
||||
await this.messagingTelemetryService.track({
|
||||
eventName: 'partial_message_list_fetch.started',
|
||||
workspaceId,
|
||||
connectedAccountId,
|
||||
connectedAccountId: connectedAccount.id,
|
||||
messageChannelId: messageChannel.id,
|
||||
});
|
||||
|
||||
@ -107,7 +101,7 @@ export class MessagingMessageListFetchJob
|
||||
await this.messagingTelemetryService.track({
|
||||
eventName: 'partial_message_list_fetch.completed',
|
||||
workspaceId,
|
||||
connectedAccountId,
|
||||
connectedAccountId: connectedAccount.id,
|
||||
messageChannelId: messageChannel.id,
|
||||
});
|
||||
|
||||
@ -121,7 +115,7 @@ export class MessagingMessageListFetchJob
|
||||
await this.messagingTelemetryService.track({
|
||||
eventName: 'full_message_list_fetch.started',
|
||||
workspaceId,
|
||||
connectedAccountId,
|
||||
connectedAccountId: connectedAccount.id,
|
||||
messageChannelId: messageChannel.id,
|
||||
});
|
||||
|
||||
@ -134,7 +128,7 @@ export class MessagingMessageListFetchJob
|
||||
await this.messagingTelemetryService.track({
|
||||
eventName: 'full_message_list_fetch.completed',
|
||||
workspaceId,
|
||||
connectedAccountId,
|
||||
connectedAccountId: connectedAccount.id,
|
||||
messageChannelId: messageChannel.id,
|
||||
});
|
||||
|
||||
|
||||
@ -7,11 +7,15 @@ import { ConnectedAccountRepository } from 'src/modules/connected-account/reposi
|
||||
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||
import { MessageChannelRepository } from 'src/modules/messaging/common/repositories/message-channel.repository';
|
||||
import { MessagingTelemetryService } from 'src/modules/messaging/common/services/messaging-telemetry.service';
|
||||
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
import {
|
||||
MessageChannelSyncStage,
|
||||
MessageChannelWorkspaceEntity,
|
||||
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
import { MessagingGmailMessagesImportService } from 'src/modules/messaging/message-import-manager/drivers/gmail/services/messaging-gmail-messages-import.service';
|
||||
import { isThrottled } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-throttled';
|
||||
|
||||
export type MessagingMessagesImportJobData = {
|
||||
messageChannelId: string;
|
||||
workspaceId: string;
|
||||
};
|
||||
|
||||
@ -29,43 +33,59 @@ export class MessagingMessagesImportJob
|
||||
) {}
|
||||
|
||||
async handle(data: MessagingMessagesImportJobData): Promise<void> {
|
||||
const { workspaceId } = data;
|
||||
const { messageChannelId, workspaceId } = data;
|
||||
|
||||
const messageChannels =
|
||||
await this.messageChannelRepository.getAll(workspaceId);
|
||||
await this.messagingTelemetryService.track({
|
||||
eventName: 'messages_import.triggered',
|
||||
workspaceId,
|
||||
messageChannelId,
|
||||
});
|
||||
|
||||
for (const messageChannel of messageChannels) {
|
||||
if (!messageChannel?.isSyncEnabled) {
|
||||
continue;
|
||||
}
|
||||
const messageChannel = await this.messageChannelRepository.getById(
|
||||
messageChannelId,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
if (!messageChannel) {
|
||||
await this.messagingTelemetryService.track({
|
||||
eventName: 'messages_import.triggered',
|
||||
eventName: 'messages_import.error.message_channel_not_found',
|
||||
messageChannelId,
|
||||
workspaceId,
|
||||
connectedAccountId: messageChannel.connectedAccountId,
|
||||
messageChannelId: messageChannel.id,
|
||||
});
|
||||
|
||||
if (
|
||||
isThrottled(
|
||||
messageChannel.syncStageStartedAt,
|
||||
messageChannel.throttleFailureCount,
|
||||
)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const connectedAccount =
|
||||
await this.connectedAccountRepository.getConnectedAccountOrThrow(
|
||||
workspaceId,
|
||||
messageChannel.connectedAccountId,
|
||||
);
|
||||
|
||||
await this.gmailFetchMessageContentFromCacheService.processMessageBatchImport(
|
||||
messageChannel,
|
||||
connectedAccount,
|
||||
workspaceId,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const connectedAccount =
|
||||
await this.connectedAccountRepository.getConnectedAccountOrThrow(
|
||||
workspaceId,
|
||||
messageChannel.connectedAccountId,
|
||||
);
|
||||
|
||||
if (!messageChannel?.isSyncEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
isThrottled(
|
||||
messageChannel.syncStageStartedAt,
|
||||
messageChannel.throttleFailureCount,
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
messageChannel.syncStage !==
|
||||
MessageChannelSyncStage.MESSAGES_IMPORT_PENDING
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.gmailFetchMessageContentFromCacheService.processMessageBatchImport(
|
||||
messageChannel,
|
||||
connectedAccount,
|
||||
workspaceId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user