Milestone 1: workspace skeleton, wire protocol, socket round-trip
Three-crate workspace per SPECS.md. varde-proto defines the full JSON Lines protocol (requests, envelopes, structured errors, events) with string-typed hashes so the crate carries no iroh dependency. The daemon binds its unix socket, loads config with flags > env > file > defaults precedence, and answers status/list; everything else returns a structured "unimplemented" error. varde-ctl maps subcommands 1:1 onto requests and round-trips status against a real daemon in the tests. Dependencies: serde/serde_json (wire format), tokio (async runtime and unix sockets), tracing/tracing-subscriber (structured logging), toml (config file), anyhow (binary-edge errors), thiserror (reserved for library errors), clap (ctl flag parsing, per spec), tempfile (dev-only, ephemeral test dirs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
//! Request dispatch and daemon state.
|
||||
|
||||
use tokio::sync::broadcast;
|
||||
use varde_proto::{Envelope, ErrorCode, Event, GlobalStatus, Request, ResponseData};
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
/// Shared daemon state. Handlers grow with the milestones; anything not
|
||||
/// yet wired returns [`ErrorCode::Unimplemented`] rather than pretending.
|
||||
pub struct Daemon {
|
||||
config: Config,
|
||||
events: broadcast::Sender<Event>,
|
||||
}
|
||||
|
||||
impl Daemon {
|
||||
pub fn new(config: Config) -> Self {
|
||||
// Capacity bounds memory if a subscriber stalls; laggards get a
|
||||
// Lagged error, not unbounded buffering.
|
||||
let (events, _) = broadcast::channel(1024);
|
||||
Daemon { config, events }
|
||||
}
|
||||
|
||||
pub fn config(&self) -> &Config {
|
||||
&self.config
|
||||
}
|
||||
|
||||
/// New receiver for the daemon event stream.
|
||||
pub fn subscribe_events(&self) -> broadcast::Receiver<Event> {
|
||||
self.events.subscribe()
|
||||
}
|
||||
|
||||
/// Handle one API request. Infallible at this level: all failures are
|
||||
/// mapped to structured error envelopes.
|
||||
pub async fn handle(&self, request: Request) -> Envelope {
|
||||
match request {
|
||||
Request::Status { hash: None } => Envelope::ok(ResponseData::Status(GlobalStatus {
|
||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
protocol: varde_proto::PROTOCOL_VERSION,
|
||||
node_id: None,
|
||||
store_path: self.config.store_dir.display().to_string(),
|
||||
pins: 0,
|
||||
connected_peers: 0,
|
||||
})),
|
||||
Request::List {} => Envelope::ok(ResponseData::Pins { pins: Vec::new() }),
|
||||
Request::Subscribe {} => Envelope::ok(ResponseData::Done {}),
|
||||
other => Envelope::err(
|
||||
ErrorCode::Unimplemented,
|
||||
format!("not implemented yet: {other:?}"),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user