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
This commit is contained in:
Vikhyath Mondreti
2025-10-15 11:52:02 -07:00
committed by GitHub
parent 061c1dff4e
commit fd67fd220c
6 changed files with 27 additions and 12 deletions
+5 -2
View File
@@ -1,6 +1,7 @@
import { createContext, Script } from 'vm' import { createContext, Script } from 'vm'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { env, isTruthy } from '@/lib/env' import { env, isTruthy } from '@/lib/env'
import { MAX_EXECUTION_DURATION } from '@/lib/execution/constants'
import { executeInE2B } from '@/lib/execution/e2b' import { executeInE2B } from '@/lib/execution/e2b'
import { CodeLanguage, DEFAULT_CODE_LANGUAGE, isValidCodeLanguage } from '@/lib/execution/languages' import { CodeLanguage, DEFAULT_CODE_LANGUAGE, isValidCodeLanguage } from '@/lib/execution/languages'
import { createLogger } from '@/lib/logs/console/logger' import { createLogger } from '@/lib/logs/console/logger'
@@ -8,7 +9,7 @@ import { validateProxyUrl } from '@/lib/security/input-validation'
import { generateRequestId } from '@/lib/utils' import { generateRequestId } from '@/lib/utils'
export const dynamic = 'force-dynamic' export const dynamic = 'force-dynamic'
export const runtime = 'nodejs' export const runtime = 'nodejs'
export const maxDuration = 60 export const maxDuration = MAX_EXECUTION_DURATION
const logger = createLogger('FunctionExecuteAPI') const logger = createLogger('FunctionExecuteAPI')
@@ -649,10 +650,12 @@ export async function POST(req: NextRequest) {
try { try {
const body = await req.json() const body = await req.json()
const { DEFAULT_EXECUTION_TIMEOUT_MS } = await import('@/lib/execution/constants')
const { const {
code, code,
params = {}, params = {},
timeout = 5000, timeout = DEFAULT_EXECUTION_TIMEOUT_MS,
language = DEFAULT_CODE_LANGUAGE, language = DEFAULT_CODE_LANGUAGE,
useLocalVM = false, useLocalVM = false,
envVars = {}, envVars = {},
@@ -1,4 +1,5 @@
import { beforeEach, describe, expect, it, type Mock, vi } from 'vitest' 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 { BlockType } from '@/executor/consts'
import { FunctionBlockHandler } from '@/executor/handlers/function/function-handler' import { FunctionBlockHandler } from '@/executor/handlers/function/function-handler'
import type { ExecutionContext } from '@/executor/types' import type { ExecutionContext } from '@/executor/types'
@@ -82,7 +83,7 @@ describe('FunctionBlockHandler', () => {
workflowVariables: {}, workflowVariables: {},
blockData: {}, blockData: {},
blockNameMapping: {}, blockNameMapping: {},
_context: { workflowId: mockContext.workflowId }, _context: { workflowId: mockContext.workflowId, workspaceId: mockContext.workspaceId },
} }
const expectedOutput: any = { result: 'Success' } const expectedOutput: any = { result: 'Success' }
@@ -116,7 +117,7 @@ describe('FunctionBlockHandler', () => {
workflowVariables: {}, workflowVariables: {},
blockData: {}, blockData: {},
blockNameMapping: {}, blockNameMapping: {},
_context: { workflowId: mockContext.workflowId }, _context: { workflowId: mockContext.workflowId, workspaceId: mockContext.workspaceId },
} }
const expectedOutput: any = { result: 'Success' } const expectedOutput: any = { result: 'Success' }
@@ -138,12 +139,12 @@ describe('FunctionBlockHandler', () => {
code: inputs.code, code: inputs.code,
language: 'javascript', language: 'javascript',
useLocalVM: true, useLocalVM: true,
timeout: 5000, // Default timeout timeout: DEFAULT_EXECUTION_TIMEOUT_MS,
envVars: {}, envVars: {},
workflowVariables: {}, workflowVariables: {},
blockData: {}, blockData: {},
blockNameMapping: {}, blockNameMapping: {},
_context: { workflowId: mockContext.workflowId }, _context: { workflowId: mockContext.workflowId, workspaceId: mockContext.workspaceId },
} }
await handler.execute(mockBlock, inputs, mockContext) await handler.execute(mockBlock, inputs, mockContext)
@@ -1,3 +1,4 @@
import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants'
import { DEFAULT_CODE_LANGUAGE } from '@/lib/execution/languages' import { DEFAULT_CODE_LANGUAGE } from '@/lib/execution/languages'
import { createLogger } from '@/lib/logs/console/logger' import { createLogger } from '@/lib/logs/console/logger'
import { BlockType } from '@/executor/consts' import { BlockType } from '@/executor/consts'
@@ -61,7 +62,7 @@ export class FunctionBlockHandler implements BlockHandler {
code: codeContent, code: codeContent,
language: inputs.language || DEFAULT_CODE_LANGUAGE, language: inputs.language || DEFAULT_CODE_LANGUAGE,
useLocalVM: !inputs.remoteExecution, useLocalVM: !inputs.remoteExecution,
timeout: inputs.timeout || 5000, timeout: inputs.timeout || DEFAULT_EXECUTION_TIMEOUT_MS,
envVars: context.environmentVariables || {}, envVars: context.environmentVariables || {},
workflowVariables: context.workflowVariables || {}, workflowVariables: context.workflowVariables || {},
blockData: blockData, // Pass block data for variable resolution blockData: blockData, // Pass block data for variable resolution
+10
View File
@@ -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
+2 -1
View File
@@ -7,6 +7,7 @@
* which runs JavaScript code in a secure sandbox. * which runs JavaScript code in a secure sandbox.
*/ */
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' 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 { ToolTester } from '@/tools/__test-utils__/test-tools'
import { functionExecuteTool } from '@/tools/function/execute' import { functionExecuteTool } from '@/tools/function/execute'
@@ -95,7 +96,7 @@ describe('Function Execute Tool', () => {
expect(body).toEqual({ expect(body).toEqual({
code: 'return 42', code: 'return 42',
timeout: 10000, timeout: DEFAULT_EXECUTION_TIMEOUT_MS,
envVars: {}, envVars: {},
workflowVariables: {}, workflowVariables: {},
blockData: {}, blockData: {},
+3 -4
View File
@@ -1,9 +1,8 @@
import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants'
import { DEFAULT_CODE_LANGUAGE } from '@/lib/execution/languages' import { DEFAULT_CODE_LANGUAGE } from '@/lib/execution/languages'
import type { CodeExecutionInput, CodeExecutionOutput } from '@/tools/function/types' import type { CodeExecutionInput, CodeExecutionOutput } from '@/tools/function/types'
import type { ToolConfig } from '@/tools/types' import type { ToolConfig } from '@/tools/types'
const DEFAULT_TIMEOUT = 10000 // 10 seconds
export const functionExecuteTool: ToolConfig<CodeExecutionInput, CodeExecutionOutput> = { export const functionExecuteTool: ToolConfig<CodeExecutionInput, CodeExecutionOutput> = {
id: 'function_execute', id: 'function_execute',
name: 'Function Execute', name: 'Function Execute',
@@ -38,7 +37,7 @@ export const functionExecuteTool: ToolConfig<CodeExecutionInput, CodeExecutionOu
required: false, required: false,
visibility: 'user-only', visibility: 'user-only',
description: 'Execution timeout in milliseconds', description: 'Execution timeout in milliseconds',
default: DEFAULT_TIMEOUT, default: DEFAULT_EXECUTION_TIMEOUT_MS,
}, },
envVars: { envVars: {
type: 'object', type: 'object',
@@ -85,7 +84,7 @@ export const functionExecuteTool: ToolConfig<CodeExecutionInput, CodeExecutionOu
code: codeContent, code: codeContent,
language: params.language || DEFAULT_CODE_LANGUAGE, language: params.language || DEFAULT_CODE_LANGUAGE,
useLocalVM: params.useLocalVM || false, useLocalVM: params.useLocalVM || false,
timeout: params.timeout || DEFAULT_TIMEOUT, timeout: params.timeout || DEFAULT_EXECUTION_TIMEOUT_MS,
envVars: params.envVars || {}, envVars: params.envVars || {},
workflowVariables: params.workflowVariables || {}, workflowVariables: params.workflowVariables || {},
blockData: params.blockData || {}, blockData: params.blockData || {},