From fd67fd220cb66ec0f39aee1a488ad7bbdfdcf632 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Wed, 15 Oct 2025 11:52:02 -0700 Subject: [PATCH] improvement(functions): increase function block timeout to 3 min (#1641) * improvement(functions): increase function block timeout to 3 min * fix tests * use shared constant * remove comment --- apps/sim/app/api/function/execute/route.ts | 7 +++++-- .../handlers/function/function-handler.test.ts | 9 +++++---- .../sim/executor/handlers/function/function-handler.ts | 3 ++- apps/sim/lib/execution/constants.ts | 10 ++++++++++ apps/sim/tools/function/execute.test.ts | 3 ++- apps/sim/tools/function/execute.ts | 7 +++---- 6 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 apps/sim/lib/execution/constants.ts diff --git a/apps/sim/app/api/function/execute/route.ts b/apps/sim/app/api/function/execute/route.ts index 31a5340d4..d1dc9190a 100644 --- a/apps/sim/app/api/function/execute/route.ts +++ b/apps/sim/app/api/function/execute/route.ts @@ -1,6 +1,7 @@ import { createContext, Script } from 'vm' import { type NextRequest, NextResponse } from 'next/server' import { env, isTruthy } from '@/lib/env' +import { MAX_EXECUTION_DURATION } from '@/lib/execution/constants' import { executeInE2B } from '@/lib/execution/e2b' import { CodeLanguage, DEFAULT_CODE_LANGUAGE, isValidCodeLanguage } from '@/lib/execution/languages' import { createLogger } from '@/lib/logs/console/logger' @@ -8,7 +9,7 @@ import { validateProxyUrl } from '@/lib/security/input-validation' import { generateRequestId } from '@/lib/utils' export const dynamic = 'force-dynamic' export const runtime = 'nodejs' -export const maxDuration = 60 +export const maxDuration = MAX_EXECUTION_DURATION const logger = createLogger('FunctionExecuteAPI') @@ -649,10 +650,12 @@ export async function POST(req: NextRequest) { try { const body = await req.json() + const { DEFAULT_EXECUTION_TIMEOUT_MS } = await import('@/lib/execution/constants') + const { code, params = {}, - timeout = 5000, + timeout = DEFAULT_EXECUTION_TIMEOUT_MS, language = DEFAULT_CODE_LANGUAGE, useLocalVM = false, envVars = {}, diff --git a/apps/sim/executor/handlers/function/function-handler.test.ts b/apps/sim/executor/handlers/function/function-handler.test.ts index f1054743a..ad48e0880 100644 --- a/apps/sim/executor/handlers/function/function-handler.test.ts +++ b/apps/sim/executor/handlers/function/function-handler.test.ts @@ -1,4 +1,5 @@ import { beforeEach, describe, expect, it, type Mock, vi } from 'vitest' +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants' import { BlockType } from '@/executor/consts' import { FunctionBlockHandler } from '@/executor/handlers/function/function-handler' import type { ExecutionContext } from '@/executor/types' @@ -82,7 +83,7 @@ describe('FunctionBlockHandler', () => { workflowVariables: {}, blockData: {}, blockNameMapping: {}, - _context: { workflowId: mockContext.workflowId }, + _context: { workflowId: mockContext.workflowId, workspaceId: mockContext.workspaceId }, } const expectedOutput: any = { result: 'Success' } @@ -116,7 +117,7 @@ describe('FunctionBlockHandler', () => { workflowVariables: {}, blockData: {}, blockNameMapping: {}, - _context: { workflowId: mockContext.workflowId }, + _context: { workflowId: mockContext.workflowId, workspaceId: mockContext.workspaceId }, } const expectedOutput: any = { result: 'Success' } @@ -138,12 +139,12 @@ describe('FunctionBlockHandler', () => { code: inputs.code, language: 'javascript', useLocalVM: true, - timeout: 5000, // Default timeout + timeout: DEFAULT_EXECUTION_TIMEOUT_MS, envVars: {}, workflowVariables: {}, blockData: {}, blockNameMapping: {}, - _context: { workflowId: mockContext.workflowId }, + _context: { workflowId: mockContext.workflowId, workspaceId: mockContext.workspaceId }, } await handler.execute(mockBlock, inputs, mockContext) diff --git a/apps/sim/executor/handlers/function/function-handler.ts b/apps/sim/executor/handlers/function/function-handler.ts index dac9b958c..9d7175925 100644 --- a/apps/sim/executor/handlers/function/function-handler.ts +++ b/apps/sim/executor/handlers/function/function-handler.ts @@ -1,3 +1,4 @@ +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants' import { DEFAULT_CODE_LANGUAGE } from '@/lib/execution/languages' import { createLogger } from '@/lib/logs/console/logger' import { BlockType } from '@/executor/consts' @@ -61,7 +62,7 @@ export class FunctionBlockHandler implements BlockHandler { code: codeContent, language: inputs.language || DEFAULT_CODE_LANGUAGE, useLocalVM: !inputs.remoteExecution, - timeout: inputs.timeout || 5000, + timeout: inputs.timeout || DEFAULT_EXECUTION_TIMEOUT_MS, envVars: context.environmentVariables || {}, workflowVariables: context.workflowVariables || {}, blockData: blockData, // Pass block data for variable resolution diff --git a/apps/sim/lib/execution/constants.ts b/apps/sim/lib/execution/constants.ts new file mode 100644 index 000000000..4fcdab365 --- /dev/null +++ b/apps/sim/lib/execution/constants.ts @@ -0,0 +1,10 @@ +/** + * Execution timeout constants + * + * These constants define the timeout values for code execution. + * - DEFAULT_EXECUTION_TIMEOUT_MS: The default timeout for executing user code (3 minutes) + * - MAX_EXECUTION_DURATION: The maximum duration for the API route (adds 30s buffer for overhead) + */ + +export const DEFAULT_EXECUTION_TIMEOUT_MS = 180000 // 3 minutes (180 seconds) +export const MAX_EXECUTION_DURATION = 210 // 3.5 minutes (210 seconds) - includes buffer for sandbox creation diff --git a/apps/sim/tools/function/execute.test.ts b/apps/sim/tools/function/execute.test.ts index ff9a45e48..8b778a206 100644 --- a/apps/sim/tools/function/execute.test.ts +++ b/apps/sim/tools/function/execute.test.ts @@ -7,6 +7,7 @@ * which runs JavaScript code in a secure sandbox. */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants' import { ToolTester } from '@/tools/__test-utils__/test-tools' import { functionExecuteTool } from '@/tools/function/execute' @@ -95,7 +96,7 @@ describe('Function Execute Tool', () => { expect(body).toEqual({ code: 'return 42', - timeout: 10000, + timeout: DEFAULT_EXECUTION_TIMEOUT_MS, envVars: {}, workflowVariables: {}, blockData: {}, diff --git a/apps/sim/tools/function/execute.ts b/apps/sim/tools/function/execute.ts index e8c9ca6a3..c64291e41 100644 --- a/apps/sim/tools/function/execute.ts +++ b/apps/sim/tools/function/execute.ts @@ -1,9 +1,8 @@ +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants' import { DEFAULT_CODE_LANGUAGE } from '@/lib/execution/languages' import type { CodeExecutionInput, CodeExecutionOutput } from '@/tools/function/types' import type { ToolConfig } from '@/tools/types' -const DEFAULT_TIMEOUT = 10000 // 10 seconds - export const functionExecuteTool: ToolConfig = { id: 'function_execute', name: 'Function Execute', @@ -38,7 +37,7 @@ export const functionExecuteTool: ToolConfig