From 54e68f62527e73bec3fad550944fb6cb91749e37 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 8 Mar 2023 20:24:59 +0000 Subject: [PATCH] feat: skip processing tasks over task quota --- .../backend/src/controllers/webhooks/handler.ts | 5 +++++ packages/backend/src/models/flow.ts | 16 ++++++++++++++++ packages/backend/src/routes/webhooks.ts | 2 +- packages/backend/src/services/action.ts | 13 ++++++++++--- packages/backend/src/services/flow.ts | 10 ++++++++-- 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/packages/backend/src/controllers/webhooks/handler.ts b/packages/backend/src/controllers/webhooks/handler.ts index ed8684dd..5ac8a160 100644 --- a/packages/backend/src/controllers/webhooks/handler.ts +++ b/packages/backend/src/controllers/webhooks/handler.ts @@ -14,6 +14,11 @@ export default async (request: IRequest, response: Response) => { .throwIfNotFound(); const testRun = !flow.active; + + if (!testRun) { + await flow.throwIfQuotaExceeded(); + } + const triggerStep = await flow.getTriggerStep(); const triggerCommand = await triggerStep.getTriggerCommand(); const app = await triggerStep.getApp(); diff --git a/packages/backend/src/models/flow.ts b/packages/backend/src/models/flow.ts index e0868b97..7a96b6c1 100644 --- a/packages/backend/src/models/flow.ts +++ b/packages/backend/src/models/flow.ts @@ -1,5 +1,6 @@ import { ValidationError } from 'objection'; import type { ModelOptions, QueryContext } from 'objection'; +import appConfig from '../config/app'; import ExtendedQueryBuilder from './query-builder'; import Base from './base'; import Step from './step'; @@ -129,6 +130,21 @@ class Flow extends Base { type: 'trigger', }); } + + async throwIfQuotaExceeded() { + if (!appConfig.isCloud) return; + + const user = await this.$relatedQuery('user'); + const usageData = await user.$relatedQuery('usageData'); + + const hasExceeded = await usageData.checkIfLimitExceeded(); + + if (hasExceeded) { + throw new Error('The allowed task quota has been exhausted!'); + } + + return this; + } } export default Flow; diff --git a/packages/backend/src/routes/webhooks.ts b/packages/backend/src/routes/webhooks.ts index 3bda1138..98191a0a 100644 --- a/packages/backend/src/routes/webhooks.ts +++ b/packages/backend/src/routes/webhooks.ts @@ -21,7 +21,7 @@ const exposeError = (handler: RequestHandler) => async (req: IRequest, res: Resp try { await handler(req, res, next); } catch (err) { - res.send(err); + res.status(422).send(err); } } diff --git a/packages/backend/src/services/action.ts b/packages/backend/src/services/action.ts index f1d13373..79af8b9f 100644 --- a/packages/backend/src/services/action.ts +++ b/packages/backend/src/services/action.ts @@ -1,3 +1,4 @@ +import appConfig from '../config/app'; import Step from '../models/step'; import Flow from '../models/flow'; import Execution from '../models/execution'; @@ -17,17 +18,23 @@ type ProcessActionOptions = { export const processAction = async (options: ProcessActionOptions) => { const { flowId, stepId, executionId } = options; - const step = await Step.query().findById(stepId).throwIfNotFound(); + const flow = await Flow.query().findById(flowId).throwIfNotFound(); const execution = await Execution.query() .findById(executionId) .throwIfNotFound(); + if (!execution.testRun) { + await flow.throwIfQuotaExceeded(); + } + + const step = await Step.query().findById(stepId).throwIfNotFound(); + const $ = await globalVariable({ - flow: await Flow.query().findById(flowId).throwIfNotFound(), + flow, app: await step.getApp(), step: step, connection: await step.$relatedQuery('connection'), - execution: execution, + execution, }); const priorExecutionSteps = await ExecutionStep.query().where({ diff --git a/packages/backend/src/services/flow.ts b/packages/backend/src/services/flow.ts index 9ff6d6fc..4ace0599 100644 --- a/packages/backend/src/services/flow.ts +++ b/packages/backend/src/services/flow.ts @@ -1,3 +1,4 @@ +import appConfig from '../config/app'; import Flow from '../models/flow'; import globalVariable from '../helpers/global-variable'; import EarlyExitError from '../errors/early-exit'; @@ -10,7 +11,12 @@ type ProcessFlowOptions = { }; export const processFlow = async (options: ProcessFlowOptions) => { - const flow = await Flow.query().findById(options.flowId).throwIfNotFound(); + const { testRun, flowId } = options; + const flow = await Flow.query().findById(flowId).throwIfNotFound(); + + if (!testRun) { + await flow.throwIfQuotaExceeded(); + } const triggerStep = await flow.getTriggerStep(); const triggerCommand = await triggerStep.getTriggerCommand(); @@ -20,7 +26,7 @@ export const processFlow = async (options: ProcessFlowOptions) => { connection: await triggerStep.$relatedQuery('connection'), app: await triggerStep.getApp(), step: triggerStep, - testRun: options.testRun, + testRun, }); try {