From 598ebccc2cabf1392b059f74658d20dd56094d55 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 16:08:34 +0100 Subject: [PATCH] Use wrapper --- packages/server/src/jsRunner/index.ts | 54 +-------- packages/server/src/jsRunner/vm/builtin-vm.ts | 108 ++++++++---------- 2 files changed, 53 insertions(+), 109 deletions(-) diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index e39dab1313..c572c112c9 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -1,62 +1,16 @@ import vm from "vm" import env from "../environment" import { setJSRunner, setOnErrorLog } from "@budibase/string-templates" -import { context, logging, timers } from "@budibase/backend-core" +import { logging } from "@budibase/backend-core" import tracer from "dd-trace" import { serializeError } from "serialize-error" - -type TrackerFn = (f: () => T) => T +import { BuiltInVM } from "./vm" export function init() { setJSRunner((js: string, ctx: vm.Context) => { return tracer.trace("runJS", {}, span => { - const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS - let track: TrackerFn = f => f() - if (perRequestLimit) { - const bbCtx = tracer.trace("runJS.getCurrentContext", {}, span => - context.getCurrentContext() - ) - if (bbCtx) { - if (!bbCtx.jsExecutionTracker) { - span?.addTags({ - createdExecutionTracker: true, - }) - bbCtx.jsExecutionTracker = tracer.trace( - "runJS.createExecutionTimeTracker", - {}, - span => timers.ExecutionTimeTracker.withLimit(perRequestLimit) - ) - } - span?.addTags({ - js: { - limitMS: bbCtx.jsExecutionTracker.limitMs, - elapsedMS: bbCtx.jsExecutionTracker.elapsedMS, - }, - }) - // We call checkLimit() here to prevent paying the cost of creating - // a new VM context below when we don't need to. - tracer.trace("runJS.checkLimitAndBind", {}, span => { - bbCtx.jsExecutionTracker!.checkLimit() - track = bbCtx.jsExecutionTracker!.track.bind( - bbCtx.jsExecutionTracker - ) - }) - } - } - - ctx = { - ...ctx, - alert: undefined, - setInterval: undefined, - setTimeout: undefined, - } - - vm.createContext(ctx) - return track(() => - vm.runInNewContext(js, ctx, { - timeout: env.JS_PER_INVOCATION_TIMEOUT_MS, - }) - ) + const vm = new BuiltInVM(ctx, span) + return vm.execute(js) }) }) diff --git a/packages/server/src/jsRunner/vm/builtin-vm.ts b/packages/server/src/jsRunner/vm/builtin-vm.ts index c439603acd..b4c9f775f9 100644 --- a/packages/server/src/jsRunner/vm/builtin-vm.ts +++ b/packages/server/src/jsRunner/vm/builtin-vm.ts @@ -1,75 +1,65 @@ import vm from "vm" import env from "../../environment" -import { setOnErrorLog } from "@budibase/string-templates" -import { context, logging, timers } from "@budibase/backend-core" -import tracer from "dd-trace" -import { serializeError } from "serialize-error" +import { context, timers } from "@budibase/backend-core" +import tracer, { Span } from "dd-trace" import { VM } from "@budibase/types" type TrackerFn = (f: () => T) => T export class BuiltInVM implements VM { private ctx: vm.Context + private span?: Span - constructor(ctx: vm.Context) { + constructor(ctx: vm.Context, span?: Span) { this.ctx = ctx - - if (env.LOG_JS_ERRORS) { - setOnErrorLog((error: Error) => { - logging.logWarn(JSON.stringify(serializeError(error))) - }) - } + this.span = span } execute(code: string) { - return tracer.trace("runJS", {}, span => { - const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS - let track: TrackerFn = f => f() - if (perRequestLimit) { - const bbCtx = tracer.trace("runJS.getCurrentContext", {}, span => - context.getCurrentContext() - ) - if (bbCtx) { - if (!bbCtx.jsExecutionTracker) { - span?.addTags({ - createdExecutionTracker: true, - }) - bbCtx.jsExecutionTracker = tracer.trace( - "runJS.createExecutionTimeTracker", - {}, - span => timers.ExecutionTimeTracker.withLimit(perRequestLimit) - ) - } - span?.addTags({ - js: { - limitMS: bbCtx.jsExecutionTracker.limitMs, - elapsedMS: bbCtx.jsExecutionTracker.elapsedMS, - }, - }) - // We call checkLimit() here to prevent paying the cost of creating - // a new VM context below when we don't need to. - tracer.trace("runJS.checkLimitAndBind", {}, span => { - bbCtx.jsExecutionTracker!.checkLimit() - track = bbCtx.jsExecutionTracker!.track.bind( - bbCtx.jsExecutionTracker - ) - }) - } - } - - this.ctx = { - ...this.ctx, - alert: undefined, - setInterval: undefined, - setTimeout: undefined, - } - - vm.createContext(this.ctx) - return track(() => - vm.runInNewContext(code, this.ctx, { - timeout: env.JS_PER_INVOCATION_TIMEOUT_MS, - }) + const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS + let track: TrackerFn = f => f() + if (perRequestLimit) { + const bbCtx = tracer.trace("runJS.getCurrentContext", {}, span => + context.getCurrentContext() ) - }) + if (bbCtx) { + if (!bbCtx.jsExecutionTracker) { + this.span?.addTags({ + createdExecutionTracker: true, + }) + bbCtx.jsExecutionTracker = tracer.trace( + "runJS.createExecutionTimeTracker", + {}, + span => timers.ExecutionTimeTracker.withLimit(perRequestLimit) + ) + } + this.span?.addTags({ + js: { + limitMS: bbCtx.jsExecutionTracker.limitMs, + elapsedMS: bbCtx.jsExecutionTracker.elapsedMS, + }, + }) + // We call checkLimit() here to prevent paying the cost of creating + // a new VM context below when we don't need to. + tracer.trace("runJS.checkLimitAndBind", {}, span => { + bbCtx.jsExecutionTracker!.checkLimit() + track = bbCtx.jsExecutionTracker!.track.bind(bbCtx.jsExecutionTracker) + }) + } + } + + this.ctx = { + ...this.ctx, + alert: undefined, + setInterval: undefined, + setTimeout: undefined, + } + + vm.createContext(this.ctx) + return track(() => + vm.runInNewContext(code, this.ctx, { + timeout: env.JS_PER_INVOCATION_TIMEOUT_MS, + }) + ) } }