From e6bb39deea68a18f111e967d72a833423f7c9ab4 Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Wed, 25 Mar 2026 15:22:17 +0530 Subject: [PATCH] fix: reset throttle state on channel relaunch (#18843) Relaunch jobs reset syncStage/syncStatus but not throttleFailureCount --- ...ar-relaunch-failed-calendar-channel.job.ts | 2 + ...elaunch-failed-message-channel.job.spec.ts | 75 +++++++++++++++++++ ...ing-relaunch-failed-message-channel.job.ts | 3 + 3 files changed, 80 insertions(+) create mode 100644 packages/twenty-server/src/modules/messaging/message-import-manager/jobs/__tests__/messaging-relaunch-failed-message-channel.job.spec.ts diff --git a/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/jobs/calendar-relaunch-failed-calendar-channel.job.ts b/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/jobs/calendar-relaunch-failed-calendar-channel.job.ts index 0aceb7b518..49a9b828b3 100644 --- a/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/jobs/calendar-relaunch-failed-calendar-channel.job.ts +++ b/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/jobs/calendar-relaunch-failed-calendar-channel.job.ts @@ -54,6 +54,8 @@ export class CalendarRelaunchFailedCalendarChannelJob { { syncStage: CalendarChannelSyncStage.CALENDAR_EVENT_LIST_FETCH_PENDING, syncStatus: CalendarChannelSyncStatus.ACTIVE, + throttleFailureCount: 0, + syncStageStartedAt: null, }, ); }, authContext); diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/jobs/__tests__/messaging-relaunch-failed-message-channel.job.spec.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/jobs/__tests__/messaging-relaunch-failed-message-channel.job.spec.ts new file mode 100644 index 0000000000..fc0a539bc4 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/jobs/__tests__/messaging-relaunch-failed-message-channel.job.spec.ts @@ -0,0 +1,75 @@ +import { type Provider } from '@nestjs/common'; +import { Test, type TestingModule } from '@nestjs/testing'; + +import { MessageChannelDataAccessService } from 'src/engine/metadata-modules/message-channel/data-access/services/message-channel-data-access.service'; +import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; +import { + MessageChannelSyncStage, + MessageChannelSyncStatus, + type MessageChannelWorkspaceEntity, +} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity'; +import { MessagingRelaunchFailedMessageChannelJob } from 'src/modules/messaging/message-import-manager/jobs/messaging-relaunch-failed-message-channel.job'; + +describe('MessagingRelaunchFailedMessageChannelJob', () => { + let job: MessagingRelaunchFailedMessageChannelJob; + let mockUpdate: jest.Mock; + let mockFindOne: jest.Mock; + + const workspaceId = 'workspace-id'; + const messageChannelId = 'message-channel-id'; + + beforeEach(async () => { + mockUpdate = jest.fn(); + mockFindOne = jest.fn(); + + const providers: Provider[] = [ + MessagingRelaunchFailedMessageChannelJob, + { + provide: GlobalWorkspaceOrmManager, + useValue: { + executeInWorkspaceContext: jest + .fn() + .mockImplementation((callback) => callback()), + }, + }, + { + provide: MessageChannelDataAccessService, + useValue: { + findOne: mockFindOne, + update: mockUpdate, + }, + }, + ]; + + const module: TestingModule = await Test.createTestingModule({ + providers, + }).compile(); + + job = await module.resolve(MessagingRelaunchFailedMessageChannelJob); + }); + + it('should reset throttle state when relaunching a failed channel', async () => { + mockFindOne.mockResolvedValue({ + id: messageChannelId, + syncStage: MessageChannelSyncStage.FAILED, + syncStatus: MessageChannelSyncStatus.FAILED_UNKNOWN, + throttleFailureCount: 5, + throttleRetryAfter: '2026-03-19T06:49:34.295Z', + syncStageStartedAt: '2026-03-19T06:34:34.000Z', + } as Partial); + + await job.handle({ workspaceId, messageChannelId }); + + expect(mockUpdate).toHaveBeenCalledWith( + workspaceId, + { id: messageChannelId }, + { + syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_PENDING, + syncStatus: MessageChannelSyncStatus.ACTIVE, + throttleFailureCount: 0, + throttleRetryAfter: null, + syncStageStartedAt: null, + }, + ); + }); +}); diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/jobs/messaging-relaunch-failed-message-channel.job.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/jobs/messaging-relaunch-failed-message-channel.job.ts index 8166fdbcff..2019677618 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/jobs/messaging-relaunch-failed-message-channel.job.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/jobs/messaging-relaunch-failed-message-channel.job.ts @@ -56,6 +56,9 @@ export class MessagingRelaunchFailedMessageChannelJob { { syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_PENDING, syncStatus: MessageChannelSyncStatus.ACTIVE, + throttleFailureCount: 0, + throttleRetryAfter: null, + syncStageStartedAt: null, }, ); }, authContext);