refactor(core): Centralize scaling mode (no-changelog) (#9835)

This commit is contained in:
Iván Ovejero
2024-08-07 13:50:46 +02:00
committed by GitHub
parent ee968b7163
commit e31d017bdd
17 changed files with 529 additions and 453 deletions

View File

@@ -6,14 +6,15 @@ import { AbortedExecutionRetryError } from '@/errors/aborted-execution-retry.err
import { MissingExecutionStopError } from '@/errors/missing-execution-stop.error';
import type { ActiveExecutions } from '@/ActiveExecutions';
import type { IExecutionResponse } from '@/Interfaces';
import type { Job, Queue } from '@/Queue';
import type { ScalingService } from '@/scaling/scaling.service';
import type { WaitTracker } from '@/WaitTracker';
import type { ExecutionRepository } from '@/databases/repositories/execution.repository';
import type { ExecutionRequest } from '@/executions/execution.types';
import type { ConcurrencyControlService } from '@/concurrency/concurrency-control.service';
import type { Job } from '@/scaling/types';
describe('ExecutionService', () => {
const queue = mock<Queue>();
const scalingService = mock<ScalingService>();
const activeExecutions = mock<ActiveExecutions>();
const executionRepository = mock<ExecutionRepository>();
const waitTracker = mock<WaitTracker>();
@@ -22,7 +23,7 @@ describe('ExecutionService', () => {
const executionService = new ExecutionService(
mock(),
mock(),
queue,
scalingService,
activeExecutions,
executionRepository,
mock(),
@@ -211,7 +212,7 @@ describe('ExecutionService', () => {
expect(concurrencyControl.remove).not.toHaveBeenCalled();
expect(waitTracker.stopExecution).not.toHaveBeenCalled();
expect(queue.stopJob).not.toHaveBeenCalled();
expect(scalingService.stopJob).not.toHaveBeenCalled();
});
});
@@ -224,7 +225,8 @@ describe('ExecutionService', () => {
const execution = mock<IExecutionResponse>({ id: '123', status: 'running' });
executionRepository.findSingleExecution.mockResolvedValue(execution);
waitTracker.has.mockReturnValue(false);
queue.findRunningJobBy.mockResolvedValue(mock<Job>());
const job = mock<Job>({ data: { executionId: '123' } });
scalingService.findJobsByStatus.mockResolvedValue([job]);
executionRepository.stopDuringRun.mockResolvedValue(mock<IExecutionResponse>());
/**
@@ -237,8 +239,8 @@ describe('ExecutionService', () => {
*/
expect(waitTracker.stopExecution).not.toHaveBeenCalled();
expect(activeExecutions.stopExecution).toHaveBeenCalled();
expect(queue.findRunningJobBy).toBeCalledWith({ executionId: execution.id });
expect(queue.stopJob).toHaveBeenCalled();
expect(scalingService.findJobsByStatus).toHaveBeenCalled();
expect(scalingService.stopJob).toHaveBeenCalled();
expect(executionRepository.stopDuringRun).toHaveBeenCalled();
});
@@ -250,7 +252,8 @@ describe('ExecutionService', () => {
const execution = mock<IExecutionResponse>({ id: '123', status: 'waiting' });
executionRepository.findSingleExecution.mockResolvedValue(execution);
waitTracker.has.mockReturnValue(true);
queue.findRunningJobBy.mockResolvedValue(mock<Job>());
const job = mock<Job>({ data: { executionId: '123' } });
scalingService.findJobsByStatus.mockResolvedValue([job]);
executionRepository.stopDuringRun.mockResolvedValue(mock<IExecutionResponse>());
/**
@@ -262,9 +265,8 @@ describe('ExecutionService', () => {
* Assert
*/
expect(waitTracker.stopExecution).toHaveBeenCalledWith(execution.id);
expect(activeExecutions.stopExecution).toHaveBeenCalled();
expect(queue.findRunningJobBy).toBeCalledWith({ executionId: execution.id });
expect(queue.stopJob).toHaveBeenCalled();
expect(scalingService.findJobsByStatus).toHaveBeenCalled();
expect(scalingService.stopJob).toHaveBeenCalled();
expect(executionRepository.stopDuringRun).toHaveBeenCalled();
});
});

View File

@@ -135,9 +135,11 @@ export class ExecutionRecoveryService {
return waitMs;
}
const { Queue } = await import('@/Queue');
const { ScalingService } = await import('@/scaling/scaling.service');
const queuedIds = await Container.get(Queue).getInProgressExecutionIds();
const runningJobs = await Container.get(ScalingService).findJobsByStatus(['active', 'waiting']);
const queuedIds = new Set(runningJobs.map((job) => job.data.executionId));
if (queuedIds.size === 0) {
this.logger.debug('[Recovery] Completed queue recovery check, no dangling executions');

View File

@@ -24,7 +24,7 @@ import type {
IWorkflowExecutionDataProcess,
} from '@/Interfaces';
import { NodeTypes } from '@/NodeTypes';
import { Queue } from '@/Queue';
import { ScalingService } from '@/scaling/scaling.service';
import type { ExecutionRequest, ExecutionSummaries, StopResult } from './execution.types';
import { WorkflowRunner } from '@/WorkflowRunner';
import type { IGetExecutionsQueryFilter } from '@db/repositories/execution.repository';
@@ -85,7 +85,7 @@ export class ExecutionService {
constructor(
private readonly globalConfig: GlobalConfig,
private readonly logger: Logger,
private readonly queue: Queue,
private readonly scalingService: ScalingService,
private readonly activeExecutions: ActiveExecutions,
private readonly executionRepository: ExecutionRepository,
private readonly workflowRepository: WorkflowRepository,
@@ -471,10 +471,12 @@ export class ExecutionService {
this.waitTracker.stopExecution(execution.id);
}
const job = await this.queue.findRunningJobBy({ executionId: execution.id });
const jobs = await this.scalingService.findJobsByStatus(['active', 'waiting']);
const job = jobs.find(({ data }) => data.executionId === execution.id);
if (job) {
await this.queue.stopJob(job);
await this.scalingService.stopJob(job);
} else {
this.logger.debug('Job to stop not in queue', { executionId: execution.id });
}