diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index 140881aa21..aab5a64098 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -5,13 +5,6 @@ import tracer from "dd-trace" import { IsolatedVM } from "./vm" import { context } from "@budibase/backend-core" -class ExecutionTimeoutError extends Error { - constructor(message: string) { - super(message) - this.name = "ExecutionTimeoutError" - } -} - export function init() { setJSRunner((js: string, ctx: Record) => { return tracer.trace("runJS", {}, span => { @@ -28,16 +21,6 @@ export function init() { bbCtx.vm = vm } - const perRequestLimit = env.JS_PER_REQUEST_TIME_LIMIT_MS - if (perRequestLimit) { - const cpuMs = Number(vm.cpuTime) / 1e6 - if (cpuMs > perRequestLimit) { - throw new ExecutionTimeoutError( - `CPU time limit exceeded (${cpuMs}ms > ${perRequestLimit}ms)` - ) - } - } - const result = vm.execute(js) return result diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index 0f9b11e531..150456ad03 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -7,11 +7,19 @@ import querystring from "querystring" import { BundleType, loadBundle } from "../bundles" import { VM } from "@budibase/types" +class ExecutionTimeoutError extends Error { + constructor(message: string) { + super(message) + this.name = "ExecutionTimeoutError" + } +} + export class IsolatedVM implements VM { #isolate: ivm.Isolate #vm: ivm.Context #jail: ivm.Reference #timeout: number + #perRequestLimit?: number #modules: Record< string, @@ -26,9 +34,11 @@ export class IsolatedVM implements VM { constructor({ memoryLimit, timeout, + perRequestLimit, }: { memoryLimit: number timeout: number + perRequestLimit?: number }) { this.#isolate = new ivm.Isolate({ memoryLimit }) this.#vm = this.#isolate.createContextSync() @@ -40,10 +50,7 @@ export class IsolatedVM implements VM { }) this.#timeout = timeout - } - - get cpuTime() { - return this.#isolate.cpuTime + this.#perRequestLimit = perRequestLimit } withHelpers() { @@ -115,6 +122,17 @@ export class IsolatedVM implements VM { } execute(code: string): string { + const perRequestLimit = this.#perRequestLimit + + if (perRequestLimit) { + const cpuMs = Number(this.#isolate.cpuTime) / 1e6 + if (cpuMs > perRequestLimit) { + throw new ExecutionTimeoutError( + `CPU time limit exceeded (${cpuMs}ms > ${perRequestLimit}ms)` + ) + } + } + code = [ ...Object.values(this.#modules).map(m => m.headCode), `results.out=${code};`, diff --git a/packages/types/src/sdk/vm.ts b/packages/types/src/sdk/vm.ts index 0c85cac925..3abec4d39d 100644 --- a/packages/types/src/sdk/vm.ts +++ b/packages/types/src/sdk/vm.ts @@ -1,4 +1,3 @@ export interface VM { - cpuTime: bigint execute(code: string): string }