Prerequisites
- Go (
go.moddeclaresgo 1.26.4) and a working C compiler —cmd/workerlinks DuckDB, so CGO must be enabled - Python >= 3.12 and
uv - Git access to the private
github.com/Chaintable/*repositories (both the Go and Python dependencies include private packages)
Five steps to a running task
1
Clone and install dependencies
python/.venv/; PYTHON_BIN in the next step must point to it.2
Build the worker
3
Start the worker
worker listening and executor started. All ten variables are required: without ICEBERG_NAMESPACE or BLOCKDB_BATCH_WRITE_ADDR, the process exits during config validation (WorkerFullConfig.Validate and validateProfileRuntimeConfig). ETCD_ENDPOINTS=none means the worker does not register with etcd, so no Coordinator is involved; BLOCKDB_BATCH_WRITE_ADDR can be any unreachable port, and STUB_BLOCKDB_DELAY_MS=0 switches the read path back to the devstub.4
Start the local proxy (in another terminal)
PROXY_SOCKET_PATH (in production that hop is a component of the notebook execution engine and is not shipped with this repository); local_proxy.py fills it in locally: it forwards the four WorkerService RPCs to the worker byte for byte, and shims both coordinators’ ReserveWorkerSlot onto the worker’s own RequestTaskSlot.The proxy is ready once it prints [proxy] listening on unix:/tmp/blockx-proxy.sock -> worker 127.0.0.1:9221.5
Submit a task
callList — the calls run concurrently inside the executor. When you need to map results back to their inputs, have the return value carry the input itself; in this example, message carries name.What you just submitted
The core ofsubmit.py is a piece of function code plus a call configuration:
- The entry function must be named
_, and each call receives one row ofcallListas its positional arguments. Two rows means two calls. CallListCallConfigis a Builder: it decides which calls this task expands into.ReturnValueResultHandleris a Plugin: it decides how the results are finalized.LocalTestServiceis a sample capability backend built into the worker. In function code it is an ordinary gRPC client; when the executor starts it swaps the channel for a BridgeChannel, so calls are intercepted and dispatched inside the worker process — this is the pattern for integrating a new capability backend, see Backend Adapter.
What you can see in the result
The worker’stask_finished log breaks this execution into three phases:
builder → calls → writer is the Worker’s three-phase state machine: the Builder expands the configuration into a call list, the Calls phase runs the function code concurrently in the executor, and the Writer phase hands off to the Plugin to finalize. io_backends records the capability backends this task hit and how many calls it made. See Task lifecycle for the full story.
If you get stuck
For more issues, see the FAQ section of Local development environment.
Next steps
Architecture overview
Components, core constraints, and the suggested reading order.
Task lifecycle
The complete sequence of the task you just ran as it moved through the system.
Local development environment
The full dependency table, Makefile targets, and environment variable list.
Contributing
Read this page before you change any code.