execd - OpenSandbox Execution Daemon
English | 中文
execd is the execution daemon for OpenSandbox. Built on Beego, it exposes a comprehensive HTTP API that turns external requests into runtime actions: managing Jupyter sessions, streaming code output via Server-Sent Events (SSE), executing shell commands, operating on the sandbox filesystem, and collecting host-side metrics.
Table of Contents
- Overview
- Core Features
- Architecture
- Getting Started
- Configuration
- API Reference
- Supported Languages
- Development
- Testing
- Observability
- Performance Benchmarks
- Contributing
- License
- Support
Overview
execd provides a unified interface for:
- Code execution: Python, Java, JavaScript, TypeScript, Go, and Bash
- Session management: Long-lived Jupyter kernel sessions with state
- Command execution: Synchronous and background shell commands
- File operations: Full filesystem CRUD with chunked upload/download
- Monitoring: Real-time host metrics (CPU, memory, uptime)
Core Features
Unified runtime management
- Translate REST calls into runtime requests handled by
pkg/runtime - Multiple execution backends: Jupyter, shell, etc.
- Automatic language detection and routing
- Pluggable Jupyter server configuration
Jupyter integration
- Maintain kernel sessions via
pkg/jupyter - WebSocket-based real-time communication
- Stream execution events through SSE
Command executor
- Foreground and background shell commands
- Proper signal forwarding with process groups
- Real-time stdout/stderr streaming
- Context-aware interruption
Filesystem
- CRUD helpers around the sandbox filesystem
- Glob-based file search
- Chunked upload/download with resume support
- Permission management
Observability
- Lightweight metrics endpoint (CPU, memory, uptime)
- Structured streaming logs
- SSE-based real-time monitoring
Architecture
Directory structure
| Path | Purpose |
|---|---|
main.go | Entry point; initializes Beego, CLI flags, routers |
pkg/flag/ | CLI and environment configuration |
pkg/web/ | HTTP layer (controllers, models, router, SSE helpers) |
pkg/web/controller/ | Handlers for files, code, commands, metrics |
pkg/web/model/ | Request/response models and SSE event types |
pkg/runtime/ | Dispatcher to Jupyter and shell executors |
pkg/jupyter/ | Minimal Jupyter client (kernels/sessions/WebSocket) |
pkg/jupyter/execute/ | Execution result types and stream parsers |
pkg/jupyter/session/ | Session management and lifecycle |
pkg/util/ | Utilities (safe goroutine helpers, glob helpers) |
tests/ | Test scripts and tools |
Getting Started
Prerequisites
- Go 1.24+ (as defined in
go.mod) - Jupyter Server (required for code execution)
- Docker (optional, for containerized builds)
- Make (optional, for convenience targets)
Quick Start
1. Clone and build
git clone git@github.com:alibaba/OpenSandbox.git
cd OpenSandbox/components/execd
go mod download
make build2. Start Jupyter Server
# Option 1: use the provided script
./tests/jupyter.sh
# Option 2: start manually
jupyter notebook --port=54321 --no-browser --ip=0.0.0.0 \
--NotebookApp.token='your-jupyter-token'3. Run execd
./bin/execd \
--jupyter-host=http://127.0.0.1:54321 \
--jupyter-token=your-jupyter-token \
--port=447724. Verify
curl -v http://localhost:44772/ping
# Expect HTTP 200Image build
docker build -t opensandbox/execd:dev .
# Run container
docker run -d \
-p 44772:44772 \
-e JUPYTER_HOST=http://jupyter-server \
-e JUPYTER_TOKEN=your-token \
--name execd \
opensandbox/execd:devConfiguration
Command-line flags
| Flag | Type | Default | Description |
|---|---|---|---|
--jupyter-host | string | "" | Jupyter server URL (reachable by execd) |
--jupyter-token | string | "" | Jupyter HTTP/WebSocket token |
--port | int | 44772 | HTTP listen port |
--log-level | int | 6 | Beego log level (0=Emergency, 7=Debug) |
--access-token | string | "" | Shared API secret (optional) |
--graceful-shutdown-timeout | duration | 3s | Wait time before cutting off SSE on shutdown |
Environment variables
All flags can be set via environment variables:
export JUPYTER_HOST=http://127.0.0.1:8888
export JUPYTER_TOKEN=your-tokenEnvironment variables override defaults but are superseded by explicit CLI flags.
API Reference
Supported Languages
Jupyter-based
| Language | Kernel | Highlights |
|---|---|---|
| Python | IPython | Full Jupyter protocol |
| Java | IJava | JShell-based execution |
| JavaScript | IJavaScript | Node.js runtime |
| TypeScript | ITypeScript | TS compilation + Node exec |
| Go | gophernotes | Go interpreter |
| Bash | Bash kernel | Shell scripts |
Native executors
| Mode/Language | Backend | Highlights |
|---|---|---|
command | OS exec | Synchronous shell commands |
background-command | OS exec | Detached background process |
Development
See DEVELOPMENT.md for detailed guidelines.
Testing
Unit tests
make testIntegration tests
Integration tests requiring a real Jupyter Server are skipped by default:
export JUPYTER_URL=http://localhost:8888
export JUPYTER_TOKEN=your-token
go test -v ./pkg/jupyter/...Manual testing workflow
- Start Jupyter:
./tests/jupyter.sh - Start execd:
./bin/execd --jupyter-host=http://localhost:54321 --jupyter-token=opensandboxexecdlocaltest - Execute code:
curl -X POST -H "Content-Type: application/json" \
-d '{"language":"python","code":"print(\"test\")"}' \
http://localhost:44772/codeConfiguration
API graceful shutdown window
- Env:
EXECD_API_GRACE_SHUTDOWN(e.g.500ms,2s,1m) - Flag:
--graceful-shutdown-timeout - Default:
1s
This controls how long execd keeps SSE responses (code/command runs) alive after sending the final chunk, so clients can drain tail output before the connection closes. Set to 0s to disable the grace period.
Observability
Logging
Beego leveled logger:
logs.Info("message") // info
logs.Warning("message") // warning
logs.Error("message") // error
logs.Debug("message") // debug- Env:
EXECD_LOG_FILEwrites execd logs to the given file path; when unset, logs are sent to stdout.
Log levels (0-7):
- 0: Emergency
- 1: Alert
- 2: Critical
- 3: Error
- 4: Warning
- 5: Notice
- 6: Info (default)
- 7: Debug
Metrics
/metrics exposes:
- CPU usage percent
- Memory total/used (GB)
- Memory usage percent
- Process uptime
- Current timestamp
For real-time monitoring, use /metrics/watch (SSE, 1s cadence).
Performance Benchmarks
Typical latency (localhost)
| Operation | Latency |
|---|---|
/ping | < 1ms |
/files/info | < 5ms |
| Code execution (Py) | 50-200ms |
| File upload (1MB) | 10-50ms |
| Metrics snapshot | < 10ms |
Resource usage (idle)
- Memory: ~50MB
- CPU: < 1%
- Goroutines: ~15
Scalability
- 100+ concurrent SSE connections
- File operations scale linearly with file size
- Jupyter sessions are stateful and need dedicated resources
Contributing
- Fork the repository
- Create a feature branch
- Follow coding conventions (see DEVELOPMENT.md)
- Add tests for new functionality
- Run
make fmtandmake test - Submit a pull request
License
execd is part of the OpenSandbox project. See LICENSE in the repository root.
Support
- Issues: GitHub Issues
- Documentation: OpenSandbox Docs
- Community: Discussions
This page is sourced from:
components/execd/README.md