Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/adora-project/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ Uses `goal_id` and `goal_status` metadata keys. Supports cancellation.
cargo build --all --exclude dora-node-api-python --exclude dora-operator-api-python --exclude dora-ros2-bridge-python

# Test (exclude Python + examples)
cargo test --all --exclude dora-node-api-python --exclude dora-operator-api-python --exclude dora-ros2-bridge-python --exclude dora-cli-api-python --exclude dora-examples
cargo test --all --exclude dora-node-api-python --exclude dora-operator-api-python --exclude dora-ros2-bridge-python --exclude dora-runtime-python --exclude dora-cli-api-python --exclude dora-examples

# Single crate
cargo test -p dora-core
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/cargo-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ jobs:
publish_if_not_exists dora-coordinator
publish_if_not_exists dora-daemon
publish_if_not_exists dora-operator-api-python
publish_if_not_exists dora-runtime
# The former `dora-runtime`, split per language. `dora-cli` depends on
# `dora-runtime-shared-lib` (→ `-api`), so both must land first.
publish_if_not_exists dora-runtime-api
publish_if_not_exists dora-runtime-shared-lib
publish_if_not_exists dora-runtime-python
publish_if_not_exists dora-cli

# Publish ROS2 bridge (before the cxx APIs, which optionally
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ jobs:
- name: Check examples compile
run: cargo check --examples
# ...nor does it build test targets, so the `#[cfg(test)]` modules of
# the three PyO3 crates were type-checked nowhere: they're excluded
# the PyO3 crates were type-checked nowhere: they're excluded
# from `cargo test` (see the `test` job) and from clippy above, and
# `cargo check --all` only covers their lib targets. A syntax error in
# one of those test modules could ship. This is rmeta-only and `Check`
Expand All @@ -189,6 +189,7 @@ jobs:
-p dora-node-api-python
-p dora-operator-api-python
-p dora-ros2-bridge-python
-p dora-runtime-python

test:
# Linux-only on PR CI (#1716). macOS + Windows coverage runs in nightly.
Expand Down Expand Up @@ -239,13 +240,16 @@ jobs:
# The PyO3 crates stay excluded here — their test binaries link
# libpython, and this job sets up no interpreter. Their unit tests run
# in `contract-tests`, which does; keep that step in sync if this list
# changes.
# changes. `dora-runtime-python` is one of them: it links pyo3 like the
# rest, and only its own targets are skipped — the lib still builds
# above, as a dependency of dora-cli-api-python.
- name: Test
run: >
cargo test --all
--exclude dora-node-api-python
--exclude dora-operator-api-python
--exclude dora-ros2-bridge-python
--exclude dora-runtime-python
--exclude dora-cli-api-python
--exclude dora-examples

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,7 @@ jobs:
--exclude dora-node-api-python
--exclude dora-operator-api-python
--exclude dora-ros2-bridge-python
--exclude dora-runtime-python
--exclude dora-cli-api-python
--exclude dora-examples

Expand Down Expand Up @@ -1847,6 +1848,7 @@ jobs:
--exclude dora-node-api-python
--exclude dora-operator-api-python
--exclude dora-ros2-bridge-python
--exclude dora-runtime-python
--exclude dora-cli-api-python
- name: Check (cross)
if: matrix.cross
Expand All @@ -1855,6 +1857,7 @@ jobs:
--exclude dora-node-api-python
--exclude dora-operator-api-python
--exclude dora-ros2-bridge-python
--exclude dora-runtime-python
--exclude dora-cli-api-python

# ===== ROS2 bridge basic checks =====
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ jobs:
dora-coordinator
dora-daemon
dora-operator-api-python
dora-runtime
dora-runtime-api
dora-runtime-shared-lib
dora-runtime-python
dora-cli
dora-ros2-bridge-msg-gen
dora-ros2-bridge
Expand Down
15 changes: 15 additions & 0 deletions .pr-bodies/2777.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Splits the monolithic `dora-runtime` into a language-neutral SDK plus per-language backend crates, and table-drives the daemon's runtime spawn logic. Behavior-preserving — no descriptor/YAML changes.

- `dora-runtime-api` — the SDK: operator event loop, node harness, `RuntimeHandle`, and the `OperatorRunner` backend trait + `main(runner)` entry.
- `dora-runtime-shared-lib` — libloading/C-ABI backend, shipped in the `dora` CLI (`dora runtime`).
- `dora-runtime-python` — PyO3 backend, the only crate linking pyo3, shipped in the wheel (`dora.start_runtime()`).

The `python` cargo feature and all `#[cfg(feature = "python")]` dispatch are gone; adding a language is now one crate implementing `OperatorRunner`. `dora-cli` no longer pulls pyo3 into its tree at all. The daemon's python/shared-library selection moves to `spawn/runtime_registry.rs`, keyed on the new `OperatorSource::runtime_name()` helper, reproducing the existing launch commands verbatim (incl. the #1797/#1805 fixes). The registry is the seam where a follow-up can add third-party runtimes via an explicit `runtimes:` map.

`dora-runtime-python` also hosts shared-library operators, by delegating to `SharedLibRunner`. That arm is load-bearing: when the daemon is itself an embedded Python process (`current_exe` ends in `python`/`python3`), `native_runtime_command` routes *native* runtime nodes to `python -uc "import dora; dora.start_runtime()"`, and the pre-split `dora-runtime` served them because it compiled the shared-library backend in unconditionally.

Publishing: both release workflows drop the now-gone `dora-runtime` for `dora-runtime-api` + `dora-runtime-shared-lib` + `dora-runtime-python`, ordered before `dora-cli` (which depends on the shared-lib backend).

`dora-runtime-python` is excluded from `cargo test --all` alongside `dora-cli-api-python` — it is a plain rlib, so unlike the `extension-module` cdylibs its test binary links libpython, and the CI test job runs without `setup-python`. Its lib still builds there, as a dependency of `dora-cli-api-python`.

Verified: `cargo test --all` (only the two known container-local `rmw_zenoh_pubsub` failures, which need multicast), `clippy --all -D warnings`, `fmt --check`, `cargo check --examples`, `make qa-fast`, and an end-to-end shared-library operator dataflow (daemon → runtime → dlopen'd operator → sink, all green).
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ Important packages:
- `binaries/cli`: `dora` CLI
- `binaries/daemon`: local process manager and transport bridge
- `binaries/coordinator`: distributed orchestration
- `binaries/runtime`: in-process operator runtime
- `binaries/runtime-api`: language-neutral operator runtime SDK (`OperatorRunner` trait + event loop)
- `binaries/runtime-shared-lib`: shared-library (C ABI) operator runtime backend (in the `dora` CLI)
- `binaries/runtime-python`: Python (PyO3) operator runtime backend (in the Python wheel)
- `libraries/core`: descriptor parsing and shared build/runtime utilities
- `libraries/message`: protocol and message definitions
- `apis/rust/node`: Rust node API
Expand Down Expand Up @@ -74,6 +76,7 @@ cargo test --all \
--exclude dora-node-api-python \
--exclude dora-operator-api-python \
--exclude dora-ros2-bridge-python \
--exclude dora-runtime-python \
--exclude dora-cli-api-python \
--exclude dora-examples

Expand Down Expand Up @@ -153,6 +156,7 @@ cargo test --all \
--exclude dora-node-api-python \
--exclude dora-operator-api-python \
--exclude dora-ros2-bridge-python \
--exclude dora-runtime-python \
--exclude dora-cli-api-python \
--exclude dora-examples
```
Expand Down
14 changes: 9 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ cargo build -p dora-daemon
cargo check --all

# Test all (excluding Python)
cargo test --all --exclude dora-node-api-python --exclude dora-operator-api-python --exclude dora-ros2-bridge-python
cargo test --all --exclude dora-runtime-python --exclude dora-node-api-python --exclude dora-operator-api-python --exclude dora-ros2-bridge-python

# Test single package
cargo test -p dora-core
Expand Down Expand Up @@ -58,7 +58,9 @@ dora run examples/python-dataflow/dataflow.yml --uv --stop-after 10s
| `binaries/cli` | dora-cli | CLI binary (`dora` command) - build, run, stop dataflows |
| `binaries/daemon` | dora-daemon | Spawns nodes, manages local shared-memory/TCP communication |
| `binaries/coordinator` | dora-coordinator | Orchestrates distributed multi-daemon deployments |
| `binaries/runtime` | dora-runtime | In-process operator execution runtime |
| `binaries/runtime-api` | dora-runtime-api | Language-neutral operator runtime SDK (event loop, node harness, `OperatorRunner` trait) |
| `binaries/runtime-shared-lib` | dora-runtime-shared-lib | Shared-library (C ABI) operator runtime backend; shipped in the `dora` CLI (`dora runtime`) |
| `binaries/runtime-python` | dora-runtime-python | Python (PyO3) operator runtime backend; shipped in the Python wheel (`dora.start_runtime()`) |
| `libraries/message` | dora-message | All inter-component message types and protocol definitions |
| `libraries/core` | dora-core | Dataflow descriptor parsing, build utilities, Zenoh config |
| `apis/rust/node` | dora-node-api | Rust API for writing custom nodes |
Expand Down Expand Up @@ -133,6 +135,7 @@ cargo test --all \
--exclude dora-node-api-python \
--exclude dora-operator-api-python \
--exclude dora-ros2-bridge-python \
--exclude dora-runtime-python \
--exclude dora-cli-api-python \
--exclude dora-examples

Expand All @@ -142,9 +145,10 @@ cargo test --all \
cargo check --examples

# 5. Only if you touched a PyO3 crate (apis/python/node, apis/python/operator,
# libraries/extensions/ros2-bridge/python): their unit tests are excluded from
# the `cargo test --all` above because the test binaries link libpython, so run
# them explicitly. CI runs the same command in ci.yml's `contract-tests` job.
# libraries/extensions/ros2-bridge/python, binaries/runtime-python): their unit
# tests are excluded from the `cargo test --all` above because the test binaries
# link libpython, so run them explicitly. CI runs the same command in ci.yml's
# `contract-tests` job.
make qa-test-python

# Quick single-crate check while iterating:
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Running a command for the whole workspace is possible by passing `--workspace`.
cargo build --all --exclude dora-node-api-python --exclude dora-operator-api-python --exclude dora-ros2-bridge-python

# Test all
cargo test --all --exclude dora-node-api-python --exclude dora-operator-api-python --exclude dora-ros2-bridge-python
cargo test --all --exclude dora-runtime-python --exclude dora-node-api-python --exclude dora-operator-api-python --exclude dora-ros2-bridge-python

# Lint
cargo clippy --all -- -D warnings
Expand Down
55 changes: 45 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ members = [
"binaries/cli",
"binaries/coordinator",
"binaries/daemon",
"binaries/runtime",
"binaries/runtime-api",
"binaries/runtime-shared-lib",
"binaries/runtime-python",
"binaries/mavlink2-bridge-node",
"binaries/ros2-bridge-node",
"examples/rust-dataflow/node",
Expand Down Expand Up @@ -123,7 +125,9 @@ dora-download = { version = "1.0.0-rc.4", path = "libraries/extensions/download"
dora-log-utils = { version = "1.0.0-rc.4", path = "libraries/log-utils" }
dora-coordinator-store = { version = "1.0.0-rc.4", path = "libraries/coordinator-store" }
dora-cli = { version = "1.0.0-rc.4", path = "binaries/cli" }
dora-runtime = { version = "1.0.0-rc.4", path = "binaries/runtime" }
dora-runtime-api = { version = "1.0.0-rc.4", path = "binaries/runtime-api" }
dora-runtime-shared-lib = { version = "1.0.0-rc.4", path = "binaries/runtime-shared-lib" }
dora-runtime-python = { version = "1.0.0-rc.4", path = "binaries/runtime-python" }
dora-daemon = { version = "1.0.0-rc.4", path = "binaries/daemon" }
dora-coordinator = { version = "1.0.0-rc.4", path = "binaries/coordinator" }
dora-ros2-bridge = { version = "1.0.0-rc.4", path = "libraries/extensions/ros2-bridge" }
Expand Down
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -145,21 +145,29 @@ qa-test:
--exclude dora-node-api-python \
--exclude dora-operator-api-python \
--exclude dora-ros2-bridge-python \
--exclude dora-runtime-python \
--exclude dora-cli-api-python \
--exclude dora-examples

# The unit tests of the three PyO3 crates `qa-test` excludes. Kept a separate
# The unit tests of the PyO3 crates `qa-test` excludes. Kept a separate
# target, not folded into `qa-test`: cargo builds these crates without
# `pyo3/extension-module` (unlike the maturin wheel), so the test binaries
# link libpython directly and need an interpreter >= 3.11 with a shared
# library — a machine set up only for Rust work would start failing the
# everyday gate. CI runs this same target in ci.yml's `contract-tests` job,
# which sets Python up explicitly.
#
# `dora-runtime-python` is the operator runtime's Python backend. Its tests
# cover the cross-language arms of the runtime split — above all that a
# shared-library operator reaching the Python runtime is *delegated* to the
# shared-lib backend rather than rejected, which is what keeps native
# operators working under an embedded-Python daemon.
qa-test-python:
@cargo test --lib \
-p dora-node-api-python \
-p dora-operator-api-python \
-p dora-ros2-bridge-python
-p dora-ros2-bridge-python \
-p dora-runtime-python

qa-coverage:
@scripts/qa/coverage.sh
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ cargo build -p dora-cli
```bash
# Run all tests
cargo test --all \
--exclude dora-runtime-python \
--exclude dora-node-api-python \
--exclude dora-operator-api-python \
--exclude dora-ros2-bridge-python
Expand Down
1 change: 1 addition & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ cargo build -p dora-cli
```bash
# 运行所有测试
cargo test --all \
--exclude dora-runtime-python \
--exclude dora-node-api-python \
--exclude dora-operator-api-python \
--exclude dora-ros2-bridge-python
Expand Down
4 changes: 2 additions & 2 deletions apis/python/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ publish = false # PyO3 cdylib, shipped via PyPI as `dora-rs-cli`, not crates.io

[features]
default = ["telemetry"]
telemetry = ["dora-runtime/telemetry"]
telemetry = ["dora-runtime-python/telemetry"]

[dependencies]
dora-cli = { workspace = true, features = ["python"] }
dora-runtime = { workspace = true, features = ["tracing", "metrics", "python"] }
dora-runtime-python = { workspace = true, features = ["tracing", "metrics"] }
dora-download = { workspace = true }
dora-node-api = { workspace = true }
eyre = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion apis/python/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use pyo3::prelude::*;
/// :rtype: None
#[pyfunction]
pub fn start_runtime() -> eyre::Result<()> {
dora_runtime::main().wrap_err("Dora Runtime raised an error.")
dora_runtime_python::main().wrap_err("Dora Runtime raised an error.")
}

/// Build a Dataflow, exactly the same way as `dora build` command line tool.
Expand Down
2 changes: 1 addition & 1 deletion apis/python/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async = ["pyo3/experimental-async"]
dora-node-api = { workspace = true }
dora-message = { workspace = true }
dora-operator-api-python = { workspace = true }
dora-runtime = { workspace = true, features = ["python"] }
dora-runtime-python = { workspace = true }
dora-cli = { workspace = true, features = ["python"] }
chrono = { version = "0.4", features = ["serde"] }
pyo3.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion apis/python/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3884,7 +3884,7 @@ impl Node {
/// :rtype: None
#[pyfunction]
pub fn start_runtime() -> eyre::Result<()> {
dora_runtime::main().wrap_err("Dora Runtime raised an error.")
dora_runtime_python::main().wrap_err("Dora Runtime raised an error.")
}

/// Build a Dataflow, exactly the same way as `dora build` command line tool.
Expand Down
Loading