进程
一次提交经过的路径
1
选址
Client 向任意一个 Coordinator 调用
ReserveWorkerSlot(task_id)。Coordinator 从 etcd 心跳重建的 Worker 视图里挑一个候选,向它调用 RequestTaskSlot(task_id, ttl_ms),把 worker_addr + slot_id 交回 Client。2
提交
Client 直连
worker_addr 调用 SubmitTask(task, slot_id)。Worker 校验 slot、创建 task 上下文、固定代码快照后返回 RUNNING。不带 slot_id 时 Worker 会内联申请一次。3
取结果
Client 对同一个 Worker 调用
WatchTasks([task_id]) 订阅终态,或用 GetTaskResult(task_id) 轮询。Coordinator 不再参与。PROXY_SOCKET_PATH 指定的 UDS proxy 转发。proxy 按 gRPC method path 把 ReserveWorkerSlot 分到 block 或 bundle Coordinator,按 x-blockx-worker-addr header 把 WorkerService 请求转到对应 Worker。本地开发用 examples/local_test_service/local_proxy.py 代替这一环。
slot
slot 是 Worker 上的 task 并发额度:- 每个 Worker 有固定数量的 slot(
TASK_SLOTS,默认 50),一个 task 占一个。 RequestTaskSlot把一个空闲 slot 切到ALLOCATED并绑定task_id;TTL(Coordinator 侧SlotTTLMs = 5000)内没有SubmitTask就自动回收。SubmitTask校验通过后 slot 进入RUNNING;task 收敛到终态的那一刻 slot 就被释放,与结果保留窗口无关。- 没有中心化队列。拿不到 slot 时 Worker 返回
NoSlot(gRPCResourceExhausted),由调用方退避重试;blockx-py 会一直退避直到拿到 slot。 - Worker 本地的 slot 表是唯一真相。Coordinator 只有一份可丢弃的派生视图;多个 Coordinator 同时选中同一个 Worker 时,在 Worker 的原子容量检查处收敛。
Worker 内部
Executor 与 Worker 之间是一条 UDS 长连接:Worker 发
ExecuteCall,Executor 在用户函数发起 IO 或子调用时回 CallWaiting,Worker 处理后 ResumeCall,最后 Executor 以 CallCompleted / CallFailed 结束。Executor 不直连任何外部服务。
两套集群
同一份代码用不同的app.Profile 起成两套互不可见的集群:
task 协议、slot 状态机和心跳在两套集群里完全一致。blockx-py 按 config 与 handler 自动选集群:
BlockTableCallConfig 走 block,BlockBundleCallConfig 走 bundle,带 ReturnValueHandler 的一律走 block,InputsCallConfig 默认走 bundle。
Sync Invoker
Sync Invoker 是 task 之外的第二个入口:一次 gRPC unaryInvoke 执行一次函数并当场返回结果、call_id 和执行归因时长。它复用 Worker 的 Executor 池、UDS 协议、Function Code View 和只读 IO 子系统,但不经过 Coordinator,没有 slot、Builder 和 Writer Plugin,也拒绝所有写请求。blockx-py 的 function.call(...) 在 Executor 之外运行时走的就是它。
时间参数速查
完整表见 Task 生命周期 的”时间语义速查”。
小结
- Coordinator 只选址、只预占 slot,无状态可多实例;Worker 是执行面唯一真相。
- slot 是 Worker 上的 task 并发额度,没有中心化队列,拿不到就退避重试。
- call 在 Worker 本机的 Python Executor 子进程里执行,所有 IO 经 UDS 回到 Worker 的 IO 子系统。
- block 与 bundle 是同一份代码、不同 profile 的两套集群;Sync Invoker 是不走 task 流程的同步入口。
- 架构总览:组件图与核心约束。
- 协议与接口:gRPC、UDS 与 etcd 协议细节。
- Coordinator 与 Worker:选址、slot 表与阶段准入的实现。
- Sync Invoker:同步调用入口的实现。