前置
- Go(
go.mod声明go 1.26.4)和可用的 C 编译器 ——cmd/worker链接 DuckDB,必须开 CGO - Python ≥ 3.12 与
uv - 能通过 git 访问
github.com/Chaintable/*私有仓库(Go 与 Python 依赖都有私有包)
五步跑通
1
克隆并装依赖
python/.venv/ 建出 executor 用的 venv,下一步的 PYTHON_BIN 要指向它。2
编译 worker
3
启动 worker
worker listening 和 executor started 就绪。这十项都是必需的:少了 ICEBERG_NAMESPACE 或 BLOCKDB_BATCH_WRITE_ADDR,进程在配置校验阶段直接退出(WorkerFullConfig.Validate 与 validateProfileRuntimeConfig)。ETCD_ENDPOINTS=none 表示不注册到 etcd,也就没有 Coordinator 参与;BLOCKDB_BATCH_WRITE_ADDR 填一个不可达端口即可,STUB_BLOCKDB_DELAY_MS=0 把读路径切回 devstub。4
启动本地 proxy(另开一个终端)
PROXY_SOCKET_PATH 指定的 UDS proxy 连接(线上那一环是 notebook 执行引擎的组件,不随本仓库发布),local_proxy.py 在本地补上它:把 WorkerService 的四个 RPC 字节级转发给 worker,并把两套 coordinator 的 ReserveWorkerSlot 垫成对 worker 自己的 RequestTaskSlot。输出 [proxy] listening on unix:/tmp/blockx-proxy.sock -> worker 127.0.0.1:9221 即就绪。5
提交 task
callList 的行序一致 —— 多次调用在 executor 内并发执行。需要结果与入参的对应关系时,让返回值自己带上入参,本例的 message 里就带着 name。你刚才提交了什么
submit.py 的核心是一段 function code 加一份 call 配置:
- 入口函数名必须是
_,每次调用拿到callList的一行作为位置参数。两行就是两次调用。 CallListCallConfig是 Builder,决定这个 task 展开成哪些 call;ReturnValueResultHandler是 Plugin,决定结果怎么收口。LocalTestService是 worker 内置的示例能力后端。function code 里它是个普通 gRPC client,executor 启动时把 channel 换成 BridgeChannel,调用被截回 worker 进程内分派 —— 这就是接入新能力后端的范式,见 后端适配器。
结果里能看到什么
worker 的task_finished 日志把这次执行拆成了三个阶段:
builder → calls → writer 就是 Worker 的三阶段状态机:Builder 把配置展开成 call 列表,Calls 阶段在 executor 里并发跑 function code,Writer 阶段交给 Plugin 收口。io_backends 记录了这次 task 打到的能力后端与调用次数。展开讲在 Task 生命周期。
卡住了
更多问题见 本地开发环境 的常见问题一节。
下一步
架构总览
组件构成、核心约束与建议阅读顺序。
Task 生命周期
刚才那个 task 在系统里的完整时序。
本地开发环境
完整依赖表、Makefile 目标与环境变量清单。
贡献流程
改代码之前先读这页。