Add retry logic to code execution and add health check to sandbox container

This commit is contained in:
sabaimran
2025-01-28 18:46:04 -08:00
committed by Debanjum
parent f13bdc5135
commit 4a28714a08
2 changed files with 30 additions and 1 deletions

View File

@@ -14,6 +14,11 @@ services:
retries: 5
sandbox:
image: ghcr.io/khoj-ai/terrarium:latest
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 2
search:
image: docker.io/searxng/searxng:latest
volumes:

View File

@@ -1,8 +1,10 @@
import asyncio
import base64
import datetime
import logging
import mimetypes
import os
from functools import wraps
from pathlib import Path
from typing import Any, Callable, List, NamedTuple, Optional
@@ -144,6 +146,28 @@ async def generate_python_code(
return GeneratedCode(code, input_files, input_links)
def async_retry_with_backoff(retries=3, backoff_in_seconds=1):
def decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
retry_count = 0
while retry_count < retries:
try:
return await func(*args, **kwargs)
except (aiohttp.ClientError, asyncio.TimeoutError) as e:
retry_count += 1
if retry_count == retries:
raise e
wait_time = backoff_in_seconds * (2 ** (retry_count - 1)) # exponential backoff
await asyncio.sleep(wait_time)
return await func(*args, **kwargs)
return wrapper
return decorator
@async_retry_with_backoff(retries=3, backoff_in_seconds=1)
async def execute_sandboxed_python(code: str, input_data: list[dict], sandbox_url: str = SANDBOX_URL) -> dict[str, Any]:
"""
Takes code to run as a string and calls the terrarium API to execute it.
@@ -157,7 +181,7 @@ async def execute_sandboxed_python(code: str, input_data: list[dict], sandbox_ur
data = {"code": cleaned_code, "files": input_data}
async with aiohttp.ClientSession() as session:
async with session.post(sandbox_url, json=data, headers=headers) as response:
async with session.post(sandbox_url, json=data, headers=headers, timeout=30) as response:
if response.status == 200:
result: dict[str, Any] = await response.json()
result["code"] = cleaned_code