Query cache instead of database for event listener webhook, logicFunction, triggers (#17824)

## Fix
Replaced direct database queries with existing flat entity map caches
for the two that already have cache infrastructure:
- **CallDatabaseEventTriggerJobsJob** - now uses flatLogicFunctionMaps
cache via WorkspaceCacheService.getOrRecompute(), filtering in memory
for non-deleted logic functions with databaseEventTriggerSettings.
- **CallWebhookJobsJob** - now uses flatWebhookMaps cache via
WorkspaceCacheService.getOrRecompute(), filtering in memory for webhooks
matching the event's operations.
- Note: **WorkflowDatabaseEventTriggerListener** - left as-is since
WorkflowAutomatedTriggerWorkspaceEntity extends BaseWorkspaceEntity (not
SyncableEntity) and has no flat entity map cache infrastructure yet.
This commit is contained in:
Charles Bochet
2026-02-10 14:14:06 +01:00
committed by GitHub
parent 2e77a68daf
commit b7ff587b5e
6 changed files with 42 additions and 32 deletions
@@ -10,12 +10,14 @@ import { CallDatabaseEventTriggerJobsJob } from 'src/engine/core-modules/logic-f
import { RouteTriggerService } from 'src/engine/core-modules/logic-function/logic-function-trigger/triggers/route/route-trigger.service';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
@Module({
imports: [
TypeOrmModule.forFeature([LogicFunctionEntity, WorkspaceEntity]),
TokenModule,
WorkspaceDomainsModule,
WorkspaceCacheModule,
],
providers: [
LogicFunctionTriggerJob,
@@ -1,8 +1,5 @@
import { InjectRepository } from '@nestjs/typeorm';
import chunk from 'lodash.chunk';
import { isDefined } from 'twenty-shared/utils';
import { IsNull, Not, Repository } from 'typeorm';
import type { ObjectRecordEvent } from 'twenty-shared/database-events';
@@ -16,7 +13,7 @@ import {
LogicFunctionTriggerJob,
LogicFunctionTriggerJobData,
} from 'src/engine/core-modules/logic-function/logic-function-trigger/jobs/logic-function-trigger.job';
import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event-batch.type';
const DATABASE_EVENT_JOBS_CHUNK_SIZE = 20;
@@ -26,20 +23,26 @@ export class CallDatabaseEventTriggerJobsJob {
constructor(
@InjectMessageQueue(MessageQueue.logicFunctionQueue)
private readonly messageQueueService: MessageQueueService,
@InjectRepository(LogicFunctionEntity)
private readonly logicFunctionRepository: Repository<LogicFunctionEntity>,
private readonly workspaceCacheService: WorkspaceCacheService,
) {}
@Process(CallDatabaseEventTriggerJobsJob.name)
async handle(workspaceEventBatch: WorkspaceEventBatch<ObjectRecordEvent>) {
const logicFunctionsWithDatabaseEventTrigger =
await this.logicFunctionRepository.find({
where: {
workspaceId: workspaceEventBatch.workspaceId,
databaseEventTriggerSettings: Not(IsNull()),
},
select: ['id', 'databaseEventTriggerSettings', 'workspaceId'],
});
const { flatLogicFunctionMaps } =
await this.workspaceCacheService.getOrRecompute(
workspaceEventBatch.workspaceId,
['flatLogicFunctionMaps'],
);
const logicFunctionsWithDatabaseEventTrigger = Object.values(
flatLogicFunctionMaps.byUniversalIdentifier,
)
.filter(isDefined)
.filter(
(logicFunction) =>
!isDefined(logicFunction.deletedAt) &&
isDefined(logicFunction.databaseEventTriggerSettings),
);
const logicFunctionsToTrigger =
logicFunctionsWithDatabaseEventTrigger.filter((logicFunction) =>
@@ -14,7 +14,10 @@ export const transformEventBatchToEventPayloads = ({
logicFunctions,
}: {
workspaceEventBatch: WorkspaceEventBatch<ObjectRecordEvent>;
logicFunctions: LogicFunctionEntity[];
logicFunctions: Pick<
LogicFunctionEntity,
'id' | 'workspaceId' | 'databaseEventTriggerSettings'
>[];
}): LogicFunctionTriggerJobData[] => {
const result: LogicFunctionTriggerJobData[] = [];
const { events, ...batchEventInfo } = workspaceEventBatch;