mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-08 22:21:23 +00:00
* feat: add configurable timeout for evals (5-10 min) - Add timeout field to CreateRun schema with min 5, max 10, default 5 - Add timeout slider UI component to /runs/new page - Update database schema to include timeout column in runs table - Create migration to add timeout column with default value of 5 - Update runTask.ts to use configurable timeout from run settings - Pass timeout parameter through the createRun action * fix: remove unused EVALS_TIMEOUT import * fix: add timeout field to createRun calls in copyRun test - Added timeout: 5 to both createRun calls in copyRun.spec.ts - This fixes the test failure caused by the new required timeout field in the runs schema - The timeout field was added in the configurable timeout feature but the test was not updated * fix: use configurable timeout for Redis key expiration in registerRunner - Updated registerRunner function to accept timeoutSeconds parameter - Modified call in runTask.ts to pass configurable timeout instead of hardcoded EVALS_TIMEOUT - Removed unused EVALS_TIMEOUT import from redis.ts - Ensures Redis keys remain valid for the entire duration of task execution (up to 10 minutes) --------- Co-authored-by: Roo Code <roomote@roocode.com> Co-authored-by: hannesrudolph <hrudolph@gmail.com>
63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
import { createClient, type RedisClientType } from "redis"
|
|
|
|
let redis: RedisClientType | undefined
|
|
|
|
export const redisClient = async () => {
|
|
if (!redis) {
|
|
redis = createClient({ url: process.env.REDIS_URL || "redis://localhost:6379" })
|
|
redis.on("error", (error) => console.error("redis error:", error))
|
|
await redis.connect()
|
|
}
|
|
|
|
return redis
|
|
}
|
|
|
|
export const getPubSubKey = (runId: number) => `evals:${runId}`
|
|
export const getRunnersKey = (runId: number) => `runners:${runId}`
|
|
export const getHeartbeatKey = (runId: number) => `heartbeat:${runId}`
|
|
|
|
export const registerRunner = async ({
|
|
runId,
|
|
taskId,
|
|
timeoutSeconds,
|
|
}: {
|
|
runId: number
|
|
taskId: number
|
|
timeoutSeconds: number
|
|
}) => {
|
|
const redis = await redisClient()
|
|
const runnersKey = getRunnersKey(runId)
|
|
await redis.sAdd(runnersKey, `task-${taskId}:${process.env.HOSTNAME ?? process.pid}`)
|
|
await redis.expire(runnersKey, timeoutSeconds)
|
|
}
|
|
|
|
export const deregisterRunner = async ({ runId, taskId }: { runId: number; taskId: number }) => {
|
|
const redis = await redisClient()
|
|
await redis.sRem(getRunnersKey(runId), `task-${taskId}:${process.env.HOSTNAME ?? process.pid}`)
|
|
}
|
|
|
|
export const startHeartbeat = async (runId: number, seconds: number = 10) => {
|
|
const pid = process.pid.toString()
|
|
const redis = await redisClient()
|
|
const heartbeatKey = getHeartbeatKey(runId)
|
|
await redis.setEx(heartbeatKey, seconds, pid)
|
|
|
|
return setInterval(
|
|
() =>
|
|
redis.expire(heartbeatKey, seconds).catch((error) => {
|
|
console.error("heartbeat error:", error)
|
|
}),
|
|
(seconds * 1_000) / 2,
|
|
)
|
|
}
|
|
|
|
export const stopHeartbeat = async (runId: number, heartbeat: NodeJS.Timeout) => {
|
|
clearInterval(heartbeat)
|
|
|
|
try {
|
|
const redis = await redisClient()
|
|
await redis.del(getHeartbeatKey(runId))
|
|
} catch (error) {
|
|
console.error("redis.del failed:", error)
|
|
}
|
|
}
|