mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
optimize the loading of statistics
This commit is contained in:
parent
f82a8562ba
commit
3312f9d7c2
|
@ -95,7 +95,11 @@ export class WorkflowRepository extends Repository<WorkflowEntity> {
|
|||
.execute();
|
||||
}
|
||||
|
||||
async getMany(sharedWorkflowIds: string[], options?: ListQuery.Options) {
|
||||
async getMany(
|
||||
sharedWorkflowIds: string[],
|
||||
options?: ListQuery.Options,
|
||||
includeExecutionStatistics?: boolean,
|
||||
) {
|
||||
if (sharedWorkflowIds.length === 0) return { workflows: [], count: 0 };
|
||||
|
||||
if (typeof options?.filter?.projectId === 'string' && options.filter.projectId !== '') {
|
||||
|
@ -143,6 +147,10 @@ export class WorkflowRepository extends Repository<WorkflowEntity> {
|
|||
|
||||
if (isOwnedByIncluded) relations.push('shared', 'shared.project');
|
||||
|
||||
if (includeExecutionStatistics === true) {
|
||||
relations.push('statistics');
|
||||
}
|
||||
|
||||
if (typeof where.name === 'string' && where.name !== '') {
|
||||
where.name = Like(`%${where.name}%`);
|
||||
}
|
||||
|
|
|
@ -81,7 +81,14 @@ export namespace ListQuery {
|
|||
* Slim workflow returned from a list query operation.
|
||||
*/
|
||||
export namespace Workflow {
|
||||
type OptionalBaseFields = 'name' | 'active' | 'versionId' | 'createdAt' | 'updatedAt' | 'tags';
|
||||
type OptionalBaseFields =
|
||||
| 'name'
|
||||
| 'active'
|
||||
| 'versionId'
|
||||
| 'createdAt'
|
||||
| 'updatedAt'
|
||||
| 'tags'
|
||||
| 'statistics';
|
||||
|
||||
type BaseFields = Pick<WorkflowEntity, 'id'> &
|
||||
Partial<Pick<WorkflowEntity, OptionalBaseFields>>;
|
||||
|
@ -89,10 +96,12 @@ export namespace ListQuery {
|
|||
type SharedField = Partial<Pick<WorkflowEntity, 'shared'>>;
|
||||
|
||||
type OwnedByField = { ownedBy: SlimUser | null; homeProject: SlimProject | null };
|
||||
type ExecutionStatisticsField = { executionStatistics: { errors: number; successes: number } };
|
||||
|
||||
export type Plain = BaseFields;
|
||||
|
||||
export type WithSharing = BaseFields & SharedField;
|
||||
export type WithExecutionStatistics = BaseFields & ExecutionStatisticsField;
|
||||
|
||||
export type WithOwnership = BaseFields & OwnedByField;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import { WorkflowStatisticsRepository } from '@/databases/repositories/workflow-
|
|||
import { EventService } from '@/events/event.service';
|
||||
import type { WorkflowStatisticsData } from '@/interfaces';
|
||||
import { Logger } from '@/logging/logger.service';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import { UserService } from '@/services/user.service';
|
||||
import { TypedEmitter } from '@/typed-emitter';
|
||||
|
||||
|
@ -169,4 +170,21 @@ export class WorkflowStatisticsService extends TypedEmitter<WorkflowStatisticsEv
|
|||
|
||||
return data;
|
||||
}
|
||||
|
||||
addExecutionStatistics(
|
||||
entity: ListQuery.Workflow.Plain,
|
||||
): ListQuery.Workflow.Plain | ListQuery.Workflow.WithExecutionStatistics {
|
||||
const workflowStatistics = entity.statistics;
|
||||
Object.assign(entity, {
|
||||
executionStatistics: {
|
||||
errors:
|
||||
workflowStatistics?.find((s) => s.name === StatisticsNames.productionError)?.count ?? 0,
|
||||
successes:
|
||||
workflowStatistics?.find((s) => s.name === StatisticsNames.productionSuccess)?.count ?? 0,
|
||||
},
|
||||
});
|
||||
|
||||
delete entity.statistics;
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,11 @@ export class WorkflowService {
|
|||
});
|
||||
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { workflows, count } = await this.workflowRepository.getMany(sharedWorkflowIds, options);
|
||||
let { workflows, count } = await this.workflowRepository.getMany(
|
||||
sharedWorkflowIds,
|
||||
options,
|
||||
includeExecutionStatistics,
|
||||
);
|
||||
|
||||
if (hasSharing(workflows)) {
|
||||
workflows = workflows.map((w) => this.ownershipService.addOwnedByAndSharedWith(w));
|
||||
|
@ -82,21 +86,11 @@ export class WorkflowService {
|
|||
}
|
||||
|
||||
if (includeExecutionStatistics) {
|
||||
workflows = await Promise.all(
|
||||
workflows.map(async (w) => {
|
||||
const stats = await this.workflowStatisticsService.getData(w.id, 'count', 0);
|
||||
return {
|
||||
...w,
|
||||
executionStatistics: {
|
||||
errors: stats.productionError,
|
||||
successes: stats.productionSuccess,
|
||||
},
|
||||
};
|
||||
}),
|
||||
);
|
||||
workflows = workflows.map((w) => this.workflowStatisticsService.addExecutionStatistics(w));
|
||||
}
|
||||
|
||||
workflows.forEach((w) => {
|
||||
// @ts-expect-error: This is to emulate the old behaviour of removing the shared
|
||||
// field as part of `addOwnedByAndSharedWith`. We need this field in `addScopes`
|
||||
// though. So to avoid leaking the information we just delete it.
|
||||
delete w.shared;
|
||||
|
|
Loading…
Reference in a new issue