Skip to content

Commit 2f75e2d

Browse files
insight-bitclaude
andcommitted
feat(fc): add FC Operator for Alibaba Cloud Function Compute sandbox support
resolves #870 Add FC (Function Compute) Operator pattern support to ROCK framework. Components: - FCConfig: Service-level configuration (rock/config.py) - FCDeploymentConfig: API-level sandbox configuration (rock/deployments/config.py) - FCOperator: AbstractOperator implementation (rock/sandbox/operator/fc.py) - FCDeployment: WebSocket session management (rock/deployments/fc.py) - fc_rocklet: Container and Runtime deployment modes Deployment modes: - Container: custom-container runtime (recommended for production) - Runtime: custom.debian12 runtime Both configured with SESSION_EXCLUSIVE mode and x-rock-session-id header affinity. Test coverage: - test_fc_deployment.py: Config validation, lifecycle tests - test_fc_e2e.py: E2E HTTP/WebSocket tests - test_fc_rocklet_runtimes.py: Runtime config validation Change-Id: I54e2de23c55d9b4c6641d6849330a300c3ad8632 Co-developed-by: Claude <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 936d3d6 commit 2f75e2d

22 files changed

Lines changed: 4183 additions & 19 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,5 +173,6 @@ markers = [
173173
"need_docker: need docker daemon running",
174174
"need_admin: need admin start",
175175
"need_admin_and_network: need install from network",
176-
"need_database: need database Docker containers (PostgreSQL, Redis)"
176+
"need_database: need database Docker containers (PostgreSQL, Redis)",
177+
"need_fc: need FC (Function Compute) environment"
177178
]

rock-conf/rock-fc.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# =============================================================================
2+
# ROCK Admin 运行时配置 - FC 环境
3+
# =============================================================================
4+
#
5+
# 用途:ROCK Admin 服务启动时加载的运行时配置
6+
#
7+
# 使用方式:
8+
# rock admin start --env fc
9+
# 或 export ROCK_CONFIG=rock-conf/rock-fc.yml
10+
#
11+
# 注意:此文件不是函数部署配置,FC 函数部署使用
12+
# rock/deployments/fc_rocklet/*/s.yaml + s deploy
13+
#
14+
# =============================================================================
15+
#
16+
# 配置层级说明:
17+
#
18+
# ┌─────────────────────────────────────────────────────────────────────┐
19+
# │ FCConfig (Admin 服务级) - 本文件 │
20+
# │ - Admin 启动时加载,提供默认值和凭证 │
21+
# │ - 服务级设置 (region, account_id, credentials) │
22+
# └─────────────────────────────────────────────────────────────────────┘
23+
#
24+
# │ merge_with_fc_config()
25+
#
26+
# ┌─────────────────────────────────────────────────────────────────────┐
27+
# │ FCDeploymentConfig (API 调用级) │
28+
# │ - 每个 sandbox API 请求创建 │
29+
# │ - 可覆盖特定字段 (memory, cpus, timeout 等) │
30+
# │ - session_id 与 ROCK sandbox_id 1:1 映射 │
31+
# └─────────────────────────────────────────────────────────────────────┘
32+
#
33+
# │ 用于调用 FC 函数
34+
#
35+
# ┌─────────────────────────────────────────────────────────────────────┐
36+
# │ s.yaml (FC 函数部署配置) │
37+
# │ - 定义 FC 函数资源规格 │
38+
# │ - Session affinity, memory, CPU, timeout 等 │
39+
# │ - 通过 `s deploy` 命令部署 │
40+
# │ - 位置: rock/deployments/fc_rocklet/{runtime,container,adapter}/ │
41+
# └─────────────────────────────────────────────────────────────────────┘
42+
#
43+
# =============================================================================
44+
45+
# Ray 配置(FC 环境不使用 Ray 进行沙箱调度,但可用于其他分布式任务)
46+
ray:
47+
runtime_env:
48+
working_dir: ./
49+
pip: ./requirements_sandbox_actor.txt
50+
namespace: "rock-sandbox-fc"
51+
52+
# FC 配置(阿里云函数计算服务级别配置)
53+
# FC (Function Compute) 是阿里云的无服务器计算服务
54+
fc:
55+
# 连接设置
56+
region: "cn-hangzhou"
57+
account_id: null # 阿里云账号 ID,运行时从环境变量或 STS 获取
58+
59+
# 函数名(必须与 s.yaml 中部署的函数名一致)
60+
# 部署流程:选择一种方案执行 s deploy → function_name 已统一为 rock-serverless-runtime-rocklet
61+
function_name: "rock-serverless-runtime-rocklet"
62+
63+
# 凭证(建议通过环境变量或 STS 临时凭证提供)
64+
# access_key_id: null
65+
# access_key_secret: null
66+
# security_token: null
67+
68+
# 资源默认值(可被 API 调用覆盖)
69+
default_memory: 4096 # MB
70+
default_cpus: 2.0
71+
72+
# 超时默认值(单位:秒)
73+
default_session_ttl: 86400 # 会话生命周期(秒),24小时,对应 s.yaml 中的 sessionTTLInSeconds
74+
default_function_timeout: 3600.0 # 函数执行超时(秒),单次请求最大1小时
75+
default_session_idle_timeout: 1800 # 会话空闲超时(秒),30分钟,对应 s.yaml 中的 sessionIdleTimeoutInSeconds
76+
77+
# 协议设置
78+
session_affinity_header: "x-rock-session-id"
79+
80+
# 预热配置(FC 环境无本地镜像需预热)
81+
warmup:
82+
images: []

rock/config.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,36 @@ class K8sConfig:
156156
watch_reconnect_delay_seconds: int = 5 # DEPRECATED: No longer used
157157

158158

159+
@dataclass
160+
class FCConfig:
161+
"""FC (Function Compute) configuration for FC operator.
162+
163+
FC (Function Compute) is Alibaba Cloud's serverless compute service.
164+
This configuration provides default values and credentials for FC sandbox deployment.
165+
"""
166+
167+
region: str = "cn-hangzhou"
168+
account_id: str | None = None
169+
function_name: str = "rock-serverless-runtime-rocklet"
170+
171+
# Credentials
172+
access_key_id: str | None = None
173+
access_key_secret: str = field(default="", repr=False)
174+
security_token: str | None = None
175+
176+
# Resource defaults
177+
default_memory: int = 4096
178+
default_cpus: float = 2.0
179+
180+
# Timeout defaults (in seconds)
181+
default_session_ttl: int = 86400 # 会话生命周期(秒),24小时
182+
default_function_timeout: float = 3600.0 # 函数执行超时(秒),单次请求最大1小时
183+
default_session_idle_timeout: int = 1800 # 会话空闲超时(秒),30分钟
184+
185+
# Protocol settings
186+
session_affinity_header: str = "x-rock-session-id"
187+
188+
159189
@dataclass
160190
class RuntimeConfig:
161191
enable_auto_clear: bool = False
@@ -199,6 +229,7 @@ def __post_init__(self) -> None:
199229
class RockConfig:
200230
ray: RayConfig = field(default_factory=RayConfig)
201231
k8s: K8sConfig = field(default_factory=K8sConfig)
232+
fc: FCConfig = field(default_factory=FCConfig)
202233
warmup: WarmupConfig = field(default_factory=WarmupConfig)
203234
nacos: NacosConfig = field(default_factory=NacosConfig)
204235
redis: RedisConfig = field(default_factory=RedisConfig)
@@ -233,6 +264,8 @@ def from_env(cls, config_path: str | None = None):
233264
kwargs["ray"] = RayConfig(**config["ray"])
234265
if "k8s" in config:
235266
kwargs["k8s"] = K8sConfig(**config["k8s"])
267+
if "fc" in config:
268+
kwargs["fc"] = FCConfig(**config["fc"])
236269
if "warmup" in config:
237270
kwargs["warmup"] = WarmupConfig(**config["warmup"])
238271
if "nacos" in config:

rock/deployments/config.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,63 @@ def get_deployment(self) -> AbstractDeployment:
232232
return RemoteDeployment.from_config(self)
233233

234234

235+
class FCDeploymentConfig(DeploymentConfig):
236+
"""Configuration for Alibaba Cloud Function Compute deployment.
237+
238+
FC (Function Compute) is Alibaba Cloud's serverless compute service.
239+
This deployment type enables serverless sandbox execution with WebSocket
240+
session management for stateful operations.
241+
"""
242+
243+
type: Literal["fc"] = "fc"
244+
"""Deployment type discriminator."""
245+
246+
session_id: str | None = None
247+
"""FC session identifier (also serves as ROCK sandbox_id)."""
248+
249+
# Connection settings
250+
function_name: str | None = None
251+
region: str | None = None
252+
account_id: str | None = None
253+
access_key_id: str | None = None
254+
access_key_secret: str | None = Field(default=None, repr=False, exclude=True)
255+
security_token: str | None = None
256+
257+
# Resource settings
258+
memory: int | None = None
259+
cpus: float | None = None
260+
261+
# Timeout settings (in seconds)
262+
session_ttl: int | None = None
263+
session_idle_timeout: int | None = None
264+
function_timeout: float | None = None
265+
266+
def get_deployment(self) -> AbstractDeployment:
267+
from rock.deployments.fc import FCDeployment
268+
269+
return FCDeployment.from_config(self)
270+
271+
def merge_with_fc_config(self, fc_config: "FCConfig") -> "FCDeploymentConfig":
272+
"""Merge this config with FCConfig defaults."""
273+
from rock.config import FCConfig
274+
275+
return FCDeploymentConfig(
276+
type=self.type,
277+
session_id=self.session_id,
278+
function_name=self.function_name or fc_config.function_name,
279+
region=self.region or fc_config.region,
280+
account_id=self.account_id or fc_config.account_id,
281+
access_key_id=self.access_key_id or fc_config.access_key_id,
282+
access_key_secret=self.access_key_secret or fc_config.access_key_secret,
283+
security_token=self.security_token or fc_config.security_token,
284+
memory=self.memory or fc_config.default_memory,
285+
cpus=self.cpus or fc_config.default_cpus,
286+
session_ttl=self.session_ttl or fc_config.default_session_ttl,
287+
session_idle_timeout=self.session_idle_timeout or fc_config.default_session_idle_timeout,
288+
function_timeout=self.function_timeout or fc_config.default_function_timeout,
289+
)
290+
291+
235292
def get_deployment(config: DeploymentConfig) -> AbstractDeployment:
236293
"""Create a deployment instance from the given configuration.
237294

0 commit comments

Comments
 (0)