Make distribution and deployment more stable. Consolidate the logic for a generic swactor node. Signed-off-by: Zachery Aaron Shores-Chmielewski <zacheryasc@gmail.com>
4.9 KiB
Unified Swactor Node with Datastore Dashboard Management
This document summarizes the changes on the datastore-dashboard branch.
Problem
The swactor ecosystem had two separate binaries with no overlap:
swactor-node(inruntime-dashboard) — distribution + dashboard, no datastoreswactor-store-node(inswactor-datastore) — datastore + optional dashboard, no distribution
The dashboard's /datastore page was read-only (stats via SSE). The standalone datastore had its own management UI on a separate port. Neither binary gave you the full picture.
Solution
A single batteries-included swactor-node crate that combines distribution, dashboard, and datastore. The dashboard now supports full datastore CRUD and lifecycle management. Old binaries remain as lightweight alternatives.
Quick start:
cargo xtask dev-node
Opens an iroh node with in-memory datastore on dashboard port 9090.
What Changed
New files
| File | Purpose |
|---|---|
crates/swactor-node/Cargo.toml |
Unified node crate — depends on runtime-dashboard, swactor-datastore, and distribution |
crates/swactor-node/src/main.rs |
Combined binary with CLI: --transport (iroh default), --storage-path, --no-datastore, --dashboard-port, etc. Main loop merges distribution ticking with datastore GC/dissemination |
crates/datastore/src/bridge.rs |
DatastoreBridge — implements the dashboard's provider trait by sending actor messages and polling responses. DatastoreNodeFactory — spawns a fresh set of datastore actors on demand (used by the start/stop UI) |
Modified files
Cargo.toml (workspace root)
- Added
"crates/swactor-node"to workspace members.
crates/datastore/src/lib.rs
- Added
pub mod bridgebehind#[cfg(feature = "node")].
crates/runtime-dashboard/src/datastore_collector.rs
- Expanded
DatastoreStatsProvidertrait with CRUD methods:list_objects,get_object,get_data,put_data,delete_object,node_status,is_running,shutdown_datastore. All have default impls returningErr("not supported")so existingDatastoreMetricsimpl compiles unchanged. - Added
ListScopeenum (Local/Swarm). - Added
DatastoreFactorytrait for starting datastores from the dashboard.
crates/runtime-dashboard/src/lib.rs
- Added
datastore_factoryfield toDashboardHandle. - Added
set_datastore_factory()anddatastore_provider()methods. - Threads factory through to
spawn_http_server().
crates/runtime-dashboard/src/server.rs
- Switched route matching from path-only to
(method, path)tuples. - Added 8 new API routes under
/api/datastore/:GET /api/datastore/list— list objects (local or swarm scope)GET /api/datastore/get— object metadata + manifestGET /api/datastore/data— download raw bytesGET /api/datastore/status— node identityPOST /api/datastore/put— upload dataPOST /api/datastore/delete— delete objectPOST /api/datastore/start— start datastore via factoryPOST /api/datastore/shutdown— stop datastore
- SSE
datastoreevent now wraps the snapshot in an envelope:{"is_running": bool, "snapshot": ...}.
crates/runtime-dashboard/src/datastore_html.rs
- Full rewrite merging the monitoring dashboard (SSE-driven stats, event timeline, transfers) with the management UI from
ui_html.rs:- Upload panel (file input + optional name)
- Objects table with Origin column (local/remote badges) and action buttons (download, delete)
- Detail modal (hash, name, size, node, tags, chunk list)
- Toast notifications
- Lifecycle buttons: Start Datastore / Stop (shown based on
is_runningfrom SSE)
xtask/src/main.rs
- Added
dev-nodesubcommand: builds and runs the unified node with happy defaults (iroh transport, port 9090, 3 actors, in-memory datastore). - Options:
--port,--actors,--storage,--no-datastore,--tcp,--listen,--release.
Design Decisions
- Iroh is the default transport. TCP is available via
--tcpflag or--transport tcp. - Datastore is on by default (in-memory). Disable with
--no-datastore. - Dashboard-only API — no separate datastore HTTP port. The dashboard serves all CRUD routes.
- Factory pattern — even when started with
--no-datastore, the dashboard can start/stop a datastore at runtime viaDatastoreNodeFactory. - No circular dependencies —
swactor-nodesits atop the dependency graph:swactor-node->runtime-dashboard+swactor-datastore[node]. The bridge trait lives inruntime-dashboardwith default method impls. - Old binaries kept —
runtime-dashboard'sswactor-nodeandswactor-datastore'sswactor-store-nodestill work as lightweight alternatives.
Verification
cargo build -p swactor-node -p runtime-dashboard -p swactor-datastore # clean, 0 warnings
cargo test -p swactor -p distribution -p runtime-dashboard -p swactor-datastore -p swactor-node # 323 tests pass