mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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: {},
|
||||||
|
|||||||
@@ -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 || {},
|
||||||
|
|||||||
Reference in New Issue
Block a user