diff --git a/packages/server/src/events/AutomationEmitter.ts b/packages/server/src/events/AutomationEmitter.ts index 9d476d5088..3297fc7263 100644 --- a/packages/server/src/events/AutomationEmitter.ts +++ b/packages/server/src/events/AutomationEmitter.ts @@ -1,18 +1,9 @@ import { rowEmission, tableEmission } from "./utils" import mainEmitter from "./index" import env from "../environment" -import { Table, Row } from "@budibase/types" +import { Table, Row, DocumentType, App } from "@budibase/types" +import { context } from "@budibase/backend-core" -// max number of automations that can chain on top of each other -// TODO: in future make this configurable at the automation level -const MAX_AUTOMATION_CHAIN = env.SELF_HOSTED ? 5 : 0 - -/** - * Special emitter which takes the count of automation runs which have occurred and blocks an - * automation from running if it has reached the maximum number of chained automations runs. - * This essentially "fakes" the normal emitter to add some functionality in-between to stop automations - * from getting stuck endlessly chaining. - */ class AutomationEmitter { chainCount: number metadata: { automationChainCount: number } @@ -24,7 +15,23 @@ class AutomationEmitter { } } - emitRow(eventName: string, appId: string, row: Row, table?: Table) { + async getMaxAutomationChain() { + const db = context.getAppDB() + const appMetadata = await db.get(DocumentType.APP_METADATA) + let chainAutomations = appMetadata?.automations?.chainAutomations + + if (chainAutomations === true) { + return 5 + } else if (chainAutomations === undefined && env.SELF_HOSTED) { + return 5 + } else { + return 0 + } + } + + async emitRow(eventName: string, appId: string, row: Row, table?: Table) { + let MAX_AUTOMATION_CHAIN = await this.getMaxAutomationChain() + // don't emit even if we've reached max automation chain if (this.chainCount >= MAX_AUTOMATION_CHAIN) { return @@ -39,9 +46,11 @@ class AutomationEmitter { }) } - emitTable(eventName: string, appId: string, table?: Table) { + async emitTable(eventName: string, appId: string, table?: Table) { + let MAX_AUTOMATION_CHAIN = await this.getMaxAutomationChain() + // don't emit even if we've reached max automation chain - if (this.chainCount > MAX_AUTOMATION_CHAIN) { + if (this.chainCount >= MAX_AUTOMATION_CHAIN) { return } diff --git a/packages/types/src/documents/app/app.ts b/packages/types/src/documents/app/app.ts index 5bbdd86515..e1174d4fe4 100644 --- a/packages/types/src/documents/app/app.ts +++ b/packages/types/src/documents/app/app.ts @@ -23,6 +23,7 @@ export interface App extends Document { automationErrors?: AppMetadataErrors icon?: AppIcon features?: AppFeatures + automations: AutomationSettings } export interface AppInstance { @@ -67,4 +68,9 @@ export interface AppIcon { export interface AppFeatures { componentValidation?: boolean disableUserMetadata?: boolean + enableAutomationChaining?: boolean +} + +export interface AutomationSettings { + chainAutomations?: boolean }